feat: add wooden fish play template
This commit is contained in:
@@ -113,6 +113,30 @@
|
||||
- 验证方式:新增玩法 PRD 必须显式声明单图资产槽位和系列素材槽位;新增工作台测试确认没有默认聊天式 Agent 输入;skill 通过 `quick_validate.py`。
|
||||
- 关联文档:`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`、`.codex/skills/genarrative-play-type-integration/SKILL.md`、`.hermes/skills/genarrative-play-type-integration/SKILL.md`。
|
||||
|
||||
## 2026-05-20 敲木鱼玩法按完整平台纵切接入
|
||||
|
||||
- 背景:敲木鱼玩法需要对齐拼图 / 跳一跳的创作闭环,不能做成孤立 demo 或前端本地计数工具。
|
||||
- 决策:新增 `wooden-fish` 玩法,采用表单 / 图片输入工作台、单图敲击物资产槽位、敲击音效资产槽位和最多 8 条飘字配置;公开作品号前缀为 `WF-*`;运行态只在单次 run 内累计总敲击次数和词条计数。后端新增独立 `module-wooden-fish`、shared contracts、SpacetimeDB `wooden_fish_*` 表 / public views、`spacetime-client` facade 和 `/api/creation/wooden-fish/*`、`/api/runtime/wooden-fish/*` 路由,前端接入平台入口、生成页、结果页、运行态、公开详情和推荐试玩。
|
||||
- 影响范围:`CONTEXT.md`、`docs/prd/【玩法创作】敲木鱼玩法模板PRD-2026-05-20.md`、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md`、`packages/shared/src/contracts/woodenFish.ts`、`server-rs/crates/shared-contracts/src/wooden_fish.rs`、`server-rs/crates/module-wooden-fish/`、`server-rs/crates/spacetime-module/src/wooden_fish*`、`server-rs/crates/spacetime-client/src/wooden_fish.rs`、`src/components/wooden-fish-*`。
|
||||
- 验证方式:执行敲木鱼契约 / module / facade / runtime model / platform entry 定向测试、`npm run typecheck`、`npm run check:encoding`、`npm run check:spacetime-schema`、`cargo check -p api-server --manifest-path server-rs\Cargo.toml`,本地 smoke 使用 mock 短信配置后检查 `/healthz`。
|
||||
- 关联文档:`docs/prd/【玩法创作】敲木鱼玩法模板PRD-2026-05-20.md`、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md`。
|
||||
|
||||
## 2026-05-21 敲木鱼敲击音效复用通用 Vidu 音效链路
|
||||
|
||||
- 背景:敲木鱼创作需要通过“敲击音效”描述生成真实短音频,不能继续由 `spacetime-client` 合成 `/generated-wooden-fish-assets/...` 假路径;同时拼图和抓大鹅音频生成入口仍需保持关闭。
|
||||
- 决策:通用 `/api/creation/audio/sound-effect` 提交 Vidu 音效任务;`/api/creation/audio/sound-effect/{task_id}/asset` 只对木鱼 `hit_sound` 目标开放,完成查询、下载、OSS 私有对象、`asset_object` 和 entity binding 写入。木鱼 `compile-draft` / `generate-hit-sound` 在 `api-server` 内复用同一 helper 生成并注入 `hitSoundAsset`,`spacetime-client` 缺少真实 `hitSoundAsset` 时拒绝编译。拼图和抓大鹅相关目标继续返回 `410 Gone`。
|
||||
- 影响范围:`server-rs/crates/api-server/src/vector_engine_audio_generation.rs`、`server-rs/crates/api-server/src/wooden_fish.rs`、`server-rs/crates/spacetime-client/src/wooden_fish.rs`、`shared-contracts` / `packages/shared` 的 `creationAudio` 契约、敲木鱼 PRD 与平台链路文档。
|
||||
- 验证方式:执行 `cargo test -p shared-contracts creation_audio --manifest-path server-rs\Cargo.toml`、`cargo test -p spacetime-client wooden_fish --manifest-path server-rs\Cargo.toml`、`cargo test -p api-server wooden_fish --manifest-path server-rs\Cargo.toml`、`cargo test -p api-server disabled_creation_audio_targets_return_gone_except_wooden_fish_sound_effects --manifest-path server-rs\Cargo.toml`、`npm run typecheck`、`npm run check:encoding`,本地 smoke 检查 `/healthz`;真实生成需同时配置 VectorEngine 与 OSS AccessKey。
|
||||
- 关联文档:`docs/prd/【玩法创作】敲木鱼玩法模板PRD-2026-05-20.md`、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`、`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md`。
|
||||
|
||||
## 2026-05-21 敲木鱼默认敲击物使用内置透明 PNG
|
||||
|
||||
- 背景:默认敲木鱼图案若继续用“木鱼”关键词临时生成,image2 容易语义化重画并改变用户认可的原始造型。
|
||||
- 决策:默认模板使用内置资源 `/wooden-fish/default-hit-object.png` 写回 `bundled-default` 敲击物资产;仅当用户输入自定义关键词、上传参考图或主动重生成敲击物时,才走 image2 -> OSS -> asset object -> entity binding 链路。创作入口卡片、结果页、运行态和公开列表兜底统一使用该 PNG。
|
||||
- 影响范围:敲木鱼工作台默认提示词、api-server 木鱼默认资产编排、创作入口种子与迁移、平台公开卡片兜底、PRD 与平台链路文档。
|
||||
- 验证方式:默认 `compile-draft` 返回的 `hitObjectAsset.generationProvider` 应为 `bundled-default` 且 `imageSrc=/wooden-fish/default-hit-object.png`;自定义关键词或参考图仍走 image2;前端静态资源可通过 Vite 直接访问。
|
||||
- 关联文档:`docs/prd/【玩法创作】敲木鱼玩法模板PRD-2026-05-20.md`、`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`。
|
||||
|
||||
## 2026-05-19 系列素材 n*n 图集抽为 api-server 通用模块
|
||||
|
||||
- 背景:抓大鹅物品 sheet 已包含 prompt 组装、固定网格切图、绿幕 / 近白底透明化、切片 PNG 持久化和 prompt 追踪;继续留在 Match3D 私有模块会让跳一跳、后续地块 / 道具类玩法重复复制同一套算法和 OSS 元数据口径。
|
||||
|
||||
@@ -179,6 +179,14 @@
|
||||
- 验证:执行 `node scripts/generate-edutainment-tv-map-concepts.mjs --dry-run`,输出应只显示 `imageReferenceCount: 1`,不出现完整 base64。
|
||||
- 关联:`scripts/generate-edutainment-tv-map-concepts.mjs`、`docs/design/【前端体验】寓教于乐电视端乐园地图入口概念图-2026-05-18.md`。
|
||||
|
||||
## 生成图资产不能只拼 generated legacy path
|
||||
|
||||
- 现象:结果页或运行态拿到 `/generated-*-assets/.../image.png` 后图片不显示;前端 `ResolvedAssetImage` 会先调用 `/api/assets/read-url?legacyPublicPath=...`,但换签后的 OSS URL 仍指向不存在对象。
|
||||
- 原因:后端只写了看起来像生成图的 legacy path,没有真正调用 image2、上传 OSS、登记 `asset_object` 并绑定实体。`/api/assets/read-url` 只负责签名读取,不会凭空生成或补写对象。
|
||||
- 处理:玩法生成链路必须在 `api-server` 完成外部副作用:调用 VectorEngine `gpt-image-2-all`,用 `GeneratedImageAssetAdapter` 准备 `PutObject`,上传 OSS 私有对象,调用 `confirm_asset_object` 和 `bind_asset_object_to_entity`,再把返回的 `legacyPublicPath` 写入玩法 profile。
|
||||
- 验证:`cargo check -p api-server --manifest-path server-rs/Cargo.toml`;契约测试应断言前端 JSON 自带的 `hitObjectAsset` 会被忽略,spacetime-client 定向测试应断言缺少服务端注入的真实 `hitObjectAsset` 时不能编译;浏览器 Network 中 generated 图片应先换签,签名 URL 指向已存在对象。
|
||||
- 关联:`server-rs/crates/api-server/src/wooden_fish.rs`、`server-rs/crates/spacetime-client/src/wooden_fish.rs`、`src/components/ResolvedAssetImage.tsx`、`src/services/assetReadUrlService.ts`。
|
||||
|
||||
## 忘记密码后仍提示手机号或密码错误先查认证快照同步
|
||||
|
||||
- 现象:用户通过“忘记密码”重设密码后,接口返回成功或页面进入登录态,但再次使用新密码登录仍提示“手机号或密码错误”;重启后还可能出现 `Bearer JWT 版本已失效`,日志里的 token version 与本地快照不一致。
|
||||
@@ -558,7 +566,7 @@
|
||||
|
||||
- 现象:登录弹窗可以进入短信页签,但点击“获取验证码”后,手机没有收到短信。
|
||||
- 原因:本地 `.env.local` 里如果是 `SMS_AUTH_PROVIDER="mock"`,后端不会发真实短信,只会返回固定 mock 验证码;真实阿里云链路已经改为普通短信 `SendSms`,验证码由当前 `api-server` 进程本地生成、哈希存储和校验,旧 `SendSmsVerifyCode` / `CheckSmsVerifyCode` 托管验证码参数不再参与真实校验。若接口直接返回“手机号登录暂未启用”,说明当前运行中的 `api-server` 进程内 `sms_auth_enabled=false`:常见原因是修改 `.env.local` 后没有重启后端,或外层 shell 已经设置了非空 `SMS_AUTH_ENABLED` 导致 dotenv 不覆盖。历史上 cmd 里 `set SMS_AUTH_ENABLED="true"` 会把引号也传进进程,Rust bool 解析失败后保持默认 false。
|
||||
- 处理:真实短信联调时把 `.env.local` 的 `SMS_AUTH_ENABLED=true`、`SMS_AUTH_PROVIDER=aliyun` 显式打开,并确认 `ALIYUN_SMS_ENDPOINT=dysmsapi.aliyuncs.com`、`ALIYUN_SMS_SIGN_NAME=北京亓盒网络科技`、`ALIYUN_SMS_TEMPLATE_CODE=SMS_506245486`、`ALIYUN_SMS_TEMPLATE_PARAM_KEY=code` 后重启 `api-server`;如果只想验证 UI 和账号链路,则保留 `mock` 并使用 `SMS_AUTH_MOCK_VERIFY_CODE`。Shell 临时覆盖时 PowerShell 用 `$env:SMS_AUTH_ENABLED="true"`,cmd 用 `set SMS_AUTH_ENABLED=true`,不要把引号作为值的一部分。`api-server` 重启会清掉未校验的本地验证码。
|
||||
- 处理:真实短信联调时把 `.env.local` 的 `SMS_AUTH_ENABLED=true`、`SMS_AUTH_PROVIDER=aliyun` 显式打开,并确认 `ALIYUN_SMS_ENDPOINT=dysmsapi.aliyuncs.com`、`ALIYUN_SMS_SIGN_NAME=北京亓盒网络科技`、`ALIYUN_SMS_TEMPLATE_CODE=SMS_506245486`、`ALIYUN_SMS_TEMPLATE_PARAM_KEY=code` 后重启 `api-server`;如果只想验证 UI、账号链路或 `/healthz`,则保留 / 切换为 `mock` 并使用 `SMS_AUTH_MOCK_VERIFY_CODE`。注意 `npm run dev:api-server` 会先合并 `.env.local`,且 `SMS_AUTH_ENABLED`、`SMS_AUTH_PROVIDER`、`SMS_AUTH_MOCK_VERIFY_CODE` 属于允许本地文件覆盖的键;如果 `.env.local` 写着 `SMS_AUTH_PROVIDER=aliyun` 但没有 `ALIYUN_SMS_ACCESS_KEY_*`,单纯在 PowerShell 里临时设置 mock 仍可能被覆盖,health smoke 会在启动阶段报“阿里云短信 AccessKey 未配置”。不改 `.env.local` 的临时 smoke 可以直接运行 `cargo run -p api-server --manifest-path server-rs\Cargo.toml` 并在同一 shell 中显式设置 `SMS_AUTH_PROVIDER=mock`、`GENARRATIVE_API_HOST`、`GENARRATIVE_API_PORT`、`GENARRATIVE_SPACETIME_SERVER_URL`、`GENARRATIVE_SPACETIME_DATABASE`。Shell 临时覆盖时 PowerShell 用 `$env:SMS_AUTH_ENABLED="true"`,cmd 用 `set SMS_AUTH_ENABLED=true`,不要把引号作为值的一部分。`api-server` 重启会清掉未校验的本地验证码。
|
||||
- 验证:分别请求浏览器域名和 Rust API 直连的 `/api/auth/login-options`,都应返回 `["phone","password"]`;`api-server` 日志里 `provider=aliyun` 才说明真实短信链路已生效。需要直接确认平台层真实调用阿里云时,配置 `ALIYUN_SMS_ACCESS_KEY_ID`、`ALIYUN_SMS_ACCESS_KEY_SECRET` 和 `ALIYUN_SMS_REAL_TEST_PHONE_NUMBER` 后手动执行 `cargo test -p platform-auth --manifest-path server-rs/Cargo.toml aliyun_send_sms_real_provider_sends_verify_code -- --ignored --nocapture`。
|
||||
- 关联:`server-rs/crates/api-server/src/config.rs`、`scripts/dev-utils.mjs`、`docs/technical/AUTH_LOGIN_OPTIONS_DESIGN_2026-04-21.md`、`docs/technical/PHONE_SMS_REAL_PROVIDER_MANUAL_VERIFICATION_RUNBOOK_2026-04-23.md`。
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ Genarrative / 陶泥儿是一个 AI 原生互动内容与小游戏平台,把 A
|
||||
|
||||
- RPG / 自定义世界创作与运行时。
|
||||
- 拼图玩法创作、草稿、发布、运行态和排行榜。
|
||||
- 敲木鱼玩法创作、草稿、发布、运行态、公开详情和分享码。
|
||||
- 抓大鹅 Match3D 创作、2D 多视角素材生成、发布和运行态。
|
||||
- 大鱼吃小鱼、方洞挑战、视觉小说、汪汪声浪和儿童向寓教于乐玩法。
|
||||
- 账号、短信 / 密码 / 微信登录、个人资料、任务、钱包、邀请码、充值、反馈、法律信息和后台管理。
|
||||
|
||||
22
CONTEXT.md
22
CONTEXT.md
@@ -18,6 +18,28 @@ _Avoid_: 为每个玩法单独发明素材流水线、把系列素材建模成
|
||||
|
||||
## Language
|
||||
|
||||
### Wooden Fish
|
||||
|
||||
**敲木鱼**:
|
||||
轻量点击型互动玩法,玩家在单次运行中点击非功能区敲击中央物品,触发敲击音效、敲击动画、随机飘字和本次运行内的词条计数。
|
||||
_Avoid_: 长期功德账本、排行榜玩法、全局账户累计
|
||||
|
||||
**敲击物图案**:
|
||||
敲木鱼作品中被玩家点击敲击的单张物品图案;默认模板使用内置透明 PNG `/wooden-fish/default-hit-object.png`,用户自定义关键词或上传图时再使用 image2 生成最终资产,上传图只作为 image2 参考。
|
||||
_Avoid_: 直接把上传图作为运行态素材、系列素材图集
|
||||
|
||||
**敲击音效**:
|
||||
敲木鱼作品中每次有效敲击播放的短音频资产,可由描述生成、文件上传或麦克风录制产生,最终统一写回作品的敲击音效资产槽位。
|
||||
_Avoid_: 背景音乐、长音频轨道、运行态实时录音
|
||||
|
||||
**飘字**:
|
||||
每次有效敲击后从作品配置中等概率抽取词条,并在敲击物上方以“词条+1”短暂漂浮显示的文本;配置里只保存幸运、健康、财富、姻缘、幸福、事业、成功、功德等词条名本身。
|
||||
_Avoid_: 带权重奖励、账户属性、可结算货币
|
||||
|
||||
**单次 run 计数**:
|
||||
敲木鱼运行态只在当前 run 内累计总敲击次数和已出现飘字词条计数,run 结束后作为摘要保存,不形成账号级长期账本。
|
||||
_Avoid_: 用户永久功德值、跨作品累计值、排行榜积分
|
||||
|
||||
### Bark Battle
|
||||
|
||||
**汪汪声浪大作战**:
|
||||
|
||||
348
docs/prd/【玩法创作】敲木鱼玩法模板PRD-2026-05-20.md
Normal file
348
docs/prd/【玩法创作】敲木鱼玩法模板PRD-2026-05-20.md
Normal file
@@ -0,0 +1,348 @@
|
||||
# 敲木鱼玩法模板 PRD 2026-05-20
|
||||
|
||||
## 1. 目标
|
||||
|
||||
新增一个可创作、可试玩、可发布的轻量休闲玩法模板:
|
||||
|
||||
```text
|
||||
敲木鱼
|
||||
```
|
||||
|
||||
模板按平台新增玩法 SOP 接入完整闭环:
|
||||
|
||||
```text
|
||||
创作入口 -> 工作台 -> 生成页 -> 结果页 -> 试玩 -> 发布 -> 运行态 -> 公开详情/分享
|
||||
```
|
||||
|
||||
首版默认屏幕中央展示内置卡通透明敲击物图案 `/wooden-fish/default-hit-object.png`。玩家点击运行态非功能区时触发一次敲击:播放敲击音效、敲击物图案执行被敲击动画,并在敲击物上方随机飘出一条祝福词。顶部计数器只在某条祝福词首次出现时创建,之后该词每次出现都累加。计数仅属于当前单次 run,不进入账号长期账本。
|
||||
|
||||
## 2. 模板定位
|
||||
|
||||
模板 ID:
|
||||
|
||||
```text
|
||||
wooden-fish
|
||||
```
|
||||
|
||||
用户展示名:
|
||||
|
||||
```text
|
||||
敲木鱼
|
||||
```
|
||||
|
||||
公开作品号前缀:
|
||||
|
||||
```text
|
||||
WF-*
|
||||
```
|
||||
|
||||
体验关键词:
|
||||
|
||||
1. 单屏点击;
|
||||
2. 轻量解压;
|
||||
3. 飘字反馈;
|
||||
4. 单局累计;
|
||||
5. 可自定义敲击物、敲击音效和祝福词。
|
||||
|
||||
## 3. 与拼图创作流程的复用边界
|
||||
|
||||
可以复用:
|
||||
|
||||
1. 创作入口配置、入口开关和作品架;
|
||||
2. 表单/图片输入工作台;
|
||||
3. 生成过程页和生成中恢复;
|
||||
4. 结果页的返回编辑、局部重生成、试玩、发布;
|
||||
5. 公开列表、公开详情、分享码和推荐流分发;
|
||||
6. 平台资产对象、OSS 私有读取换签和音频资产持久化能力。
|
||||
|
||||
不复用:
|
||||
|
||||
1. 拼图关卡、棋盘、拼块、排行榜和关卡推进语义;
|
||||
2. 跳一跳地块图集和蓄力判定语义;
|
||||
3. 抓大鹅物品消除、五视角图集和容器语义;
|
||||
4. 任何长期功德账本、账号维度排行榜或全局累计。
|
||||
|
||||
## 4. 创作工具平台接入声明
|
||||
|
||||
- 工作台模式:表单/图片输入创作工作台
|
||||
- 创作链路:入口 -> 工作台 -> 生成页 -> 结果页 -> 试玩 -> 发布 -> 运行态
|
||||
- 单图资产槽位:
|
||||
- `slotId=hit-object`
|
||||
- `slotType=hit-object-image`
|
||||
- `slotName=敲击物图案`
|
||||
- 提示词来源:`hitObjectPrompt` 与可选 `hitObjectReferenceImageSrc`
|
||||
- 写回字段:`hitObjectAsset`
|
||||
- 是否允许历史图:允许
|
||||
- 是否允许 AI 重绘:允许;上传图只作为 image2 参考,最终运行态只消费 image2 生成图
|
||||
- 系列素材槽位:无;首版只有单图敲击物,不生成图集
|
||||
- 音频资产槽位:
|
||||
- `slotId=hit-sound`
|
||||
- `slotType=hit-sound-audio`
|
||||
- `slotName=敲击音效`
|
||||
- 来源:`hitSoundPrompt` 生成,或上传/麦克风录制音频
|
||||
- 写回字段:`hitSoundAsset`
|
||||
- 描述生成能力:复用通用创作音频接口 `/api/creation/audio/sound-effect` 的 VectorEngine Vidu 音效生成与 OSS 持久化链路
|
||||
- API 命名空间:
|
||||
- `/api/creation/wooden-fish/...`
|
||||
- `/api/runtime/wooden-fish/...`
|
||||
- 业务真相:
|
||||
- 后端裁决并持久化 session、work profile、发布状态、run 摘要和公开投影;
|
||||
- 前端只负责点击低延迟表现、音频播放、动画、飘字渲染和定期 checkpoint。
|
||||
- 创作工具模式例外:无
|
||||
- 验证命令:
|
||||
- `npm run check:encoding`
|
||||
- `npm run typecheck`
|
||||
- `cargo test -p shared-contracts wooden_fish --manifest-path server-rs/Cargo.toml`
|
||||
- `cargo test -p module-wooden-fish --manifest-path server-rs/Cargo.toml`
|
||||
- `cargo check -p api-server --manifest-path server-rs/Cargo.toml`
|
||||
- `npm run spacetime:generate`
|
||||
- `npm run check:spacetime-schema`
|
||||
- `npm run dev:api-server` 后检查 `/healthz`
|
||||
|
||||
## 5. 创作输入
|
||||
|
||||
工作台提交结构化 payload,不提交聊天消息。
|
||||
|
||||
必填字段:
|
||||
|
||||
1. `templateId = "wooden-fish"`;
|
||||
2. `workTitle`:作品标题;
|
||||
3. `hitObjectPrompt`:用户想敲的对象关键词或描述,默认“默认敲击物图案,圆润木质质感,透明背景”;
|
||||
4. `floatingWords[]`:祝福词,最多 8 条,不填或清空时使用默认祝福词。
|
||||
|
||||
可选字段:
|
||||
|
||||
1. `workDescription`:作品简介;
|
||||
2. `themeTags[]`:最多 6 个标签;
|
||||
3. `hitObjectReferenceImageSrc`:上传或历史图引用,只能作为 image2 参考,不可直接进入运行态;
|
||||
4. `hitSoundPrompt`:生成音效描述;
|
||||
5. `hitSoundAsset`:用户上传或录音产生的音频资产。
|
||||
|
||||
默认祝福词:
|
||||
|
||||
```text
|
||||
幸运
|
||||
健康
|
||||
财富
|
||||
姻缘
|
||||
幸福
|
||||
事业
|
||||
成功
|
||||
功德
|
||||
```
|
||||
|
||||
`floatingWords[]` 保存词条名本身,不保存 `+1` 后缀;运行态每次敲击时再把飘字展示为“词条+1”。
|
||||
|
||||
## 6. 生成规则
|
||||
|
||||
### 6.1 敲击物图案
|
||||
|
||||
默认模板在用户未自定义关键词且未上传参考图时,`compile-draft` 使用内置透明 PNG `/wooden-fish/default-hit-object.png` 写回 `hitObjectAsset`,`generationProvider="bundled-default"`。这张图来自 image2 对原始参考图的卡通风格化重绘,固定为模板默认资源,避免默认关键词在每次生成时改变造型。
|
||||
|
||||
用户输入自定义关键词、上传参考图,或在结果页主动重生成敲击物时,`compile-draft` 与 `regenerate-hit-object` 必须为敲击物图案生成 image2 单图资产,并由 `api-server` 注入写回 `hitObjectAsset`。前端 action 请求不得自带 `hitObjectAsset` 短路生成。如果用户上传参考图,后端只能把该图作为 image2 参考图或编辑输入;运行态不得直接使用上传图。
|
||||
|
||||
落库链路固定为:`api-server` 调用 VectorEngine `gpt-image-2-all` -> 服务端上传 OSS 私有对象 -> `confirm_asset_object` 登记资产对象 -> `bind_asset_object_to_entity` 绑定到 `entityKind='wooden_fish_work'`、`slot='hit_object'`、`assetKind='wooden_fish_hit_object'` -> 把 `legacyPublicPath` 写入 `hitObjectAsset.imageSrc`。不得只拼 `/generated-wooden-fish-assets/...` 占位路径;前端会对 generated legacy path 走 `/api/assets/read-url` 换签,OSS 中没有真实对象时图片无法显示。
|
||||
|
||||
默认图案要求:
|
||||
|
||||
1. 中央主体使用 `/wooden-fish/default-hit-object.png`;
|
||||
2. 透明背景;
|
||||
3. 适合移动端居中展示;
|
||||
4. 不包含 UI、按钮、说明文字、水印或品牌标识;
|
||||
5. 图片主体需留出敲击动画缩放空间。
|
||||
|
||||
### 6.2 敲击音效
|
||||
|
||||
音效统一写回 `hitSoundAsset`。
|
||||
|
||||
生成或写回规则:
|
||||
|
||||
1. 若 payload 已包含上传/录音音频资产,`compile-draft` 跳过音效生成,直接持久化该资产;
|
||||
2. 若 payload 只包含 `hitSoundPrompt`,`api-server` 复用通用创作音频能力提交 VectorEngine Vidu `sound_effect` 任务,轮询生成结果,下载音频,写入 OSS 私有对象,登记 `asset_object`,并绑定到 `entityKind='wooden_fish_work'`、`slot='hit_sound'`、`assetKind='wooden_fish_hit_sound'`,最后注入 `hitSoundAsset`;
|
||||
3. 若两者都没有,后端生成默认“清脆短促木鱼敲击声”;
|
||||
4. 音效资产必须包含可播放地址、对象键、asset object id、来源和可选时长;
|
||||
5. 通用创作音频接口对 `wooden_fish` 的 `hit_sound` 目标不得返回 `410 Gone`,对应 `storagePrefix='wooden_fish_assets'`;
|
||||
6. `spacetime-client` 不得自行合成 `/generated-wooden-fish-assets/...` 音效占位路径,缺少真实 `hitSoundAsset` 时必须拒绝编译。
|
||||
|
||||
### 6.3 封面
|
||||
|
||||
首版封面使用 `hitObjectAsset.imageSrc` 作为 `coverImageSrc`。不单独新增第三次图片生成。
|
||||
|
||||
## 7. 契约草案
|
||||
|
||||
`WoodenFishDraft` 至少包含:
|
||||
|
||||
1. `templateId = "wooden-fish"`;
|
||||
2. `templateName = "敲木鱼"`;
|
||||
3. `profileId`;
|
||||
4. `workTitle`;
|
||||
5. `workDescription`;
|
||||
6. `themeTags[]`;
|
||||
7. `hitObjectPrompt`;
|
||||
8. `hitObjectReferenceImageSrc`;
|
||||
9. `hitSoundPrompt`;
|
||||
10. `floatingWords[]`;
|
||||
11. `hitObjectAsset`;
|
||||
12. `hitSoundAsset`;
|
||||
13. `coverImageSrc`;
|
||||
14. `generationStatus`。
|
||||
|
||||
`WoodenFishImageAsset` 至少包含:
|
||||
|
||||
1. `assetId`;
|
||||
2. `imageSrc`;
|
||||
3. `imageObjectKey`;
|
||||
4. `assetObjectId`;
|
||||
5. `generationProvider`;
|
||||
6. `prompt`;
|
||||
7. `width`;
|
||||
8. `height`。
|
||||
|
||||
`WoodenFishAudioAsset` 至少包含:
|
||||
|
||||
1. `assetId`;
|
||||
2. `audioSrc`;
|
||||
3. `audioObjectKey`;
|
||||
4. `assetObjectId`;
|
||||
5. `source = generated | uploaded | recorded | placeholder`;
|
||||
6. `prompt`;
|
||||
7. `durationMs`。
|
||||
|
||||
`WoodenFishRunSnapshot` 至少包含:
|
||||
|
||||
1. `runId`;
|
||||
2. `profileId`;
|
||||
3. `ownerUserId`;
|
||||
4. `status = playing | finished`;
|
||||
5. `totalTapCount`;
|
||||
6. `wordCounters[]`;
|
||||
7. `startedAtMs`;
|
||||
8. `updatedAtMs`;
|
||||
9. `finishedAtMs`。
|
||||
|
||||
## 8. API 草案
|
||||
|
||||
HTTP 路由:
|
||||
|
||||
```text
|
||||
POST /api/creation/wooden-fish/sessions
|
||||
GET /api/creation/wooden-fish/sessions/{sessionId}
|
||||
POST /api/creation/wooden-fish/sessions/{sessionId}/actions
|
||||
GET /api/creation/wooden-fish/works/{profileId}
|
||||
POST /api/creation/wooden-fish/works/{profileId}/publish
|
||||
GET /api/runtime/wooden-fish/works/{profileId}
|
||||
POST /api/runtime/wooden-fish/runs
|
||||
POST /api/runtime/wooden-fish/runs/{runId}/checkpoint
|
||||
POST /api/runtime/wooden-fish/runs/{runId}/finish
|
||||
GET /api/runtime/wooden-fish/gallery
|
||||
GET /api/runtime/wooden-fish/gallery/{publicWorkCode}
|
||||
```
|
||||
|
||||
动作类型:
|
||||
|
||||
```text
|
||||
compile-draft
|
||||
regenerate-hit-object
|
||||
generate-hit-sound
|
||||
replace-hit-sound
|
||||
update-work-meta
|
||||
update-floating-words
|
||||
publish
|
||||
start-run
|
||||
checkpoint
|
||||
finish
|
||||
```
|
||||
|
||||
`compile-draft` 是长耗时动作。前端进入生成页后应展示可恢复进度;如果请求失败,标记失败前必须复读 session,确认后端是否已经生成并写回草稿。
|
||||
|
||||
## 9. SpacetimeDB 表和 view
|
||||
|
||||
新增表:
|
||||
|
||||
1. `wooden_fish_agent_session`;
|
||||
2. `wooden_fish_work_profile`;
|
||||
3. `wooden_fish_runtime_run`;
|
||||
4. `wooden_fish_event`。
|
||||
|
||||
新增 view:
|
||||
|
||||
1. `wooden_fish_gallery_card_view`:公开列表卡片投影,只暴露已发布作品;
|
||||
2. `wooden_fish_gallery_view`:公开详情兼容投影,包含图案、音效和祝福词配置。
|
||||
|
||||
新增或调整表、procedure、view 后必须同步 `migration.rs`、后端表目录、生成 bindings,并执行 `npm run check:spacetime-schema`。
|
||||
|
||||
## 10. 结果页能力
|
||||
|
||||
结果页必须展示:
|
||||
|
||||
1. 作品标题和简介;
|
||||
2. 敲击物图案;
|
||||
3. 敲击音效试听;
|
||||
4. 祝福词配置;
|
||||
5. 标签;
|
||||
6. 试玩;
|
||||
7. 发布;
|
||||
8. 返回编辑。
|
||||
|
||||
结果页必须支持:
|
||||
|
||||
1. 重生成敲击物图案;
|
||||
2. 生成、上传或替换敲击音效;
|
||||
3. 修改标题、简介和标签;
|
||||
4. 修改祝福词,最多 8 条。
|
||||
|
||||
图案重生成和音效生成是独立局部生成态,不得把已有可查看结果重新变成不可打开的全局生成中。
|
||||
|
||||
## 11. 运行态规则
|
||||
|
||||
运行态采用全屏单击模型。
|
||||
|
||||
功能区:
|
||||
|
||||
1. 顶部计数器;
|
||||
2. 设置、暂停、返回、发布分享等按钮;
|
||||
3. 结果弹层和音频授权提示。
|
||||
|
||||
点击规则:
|
||||
|
||||
1. 点击非功能区才算一次敲击;
|
||||
2. 每次敲击立即本地累加 `totalTapCount`;
|
||||
3. 随机等概率从 `floatingWords[]` 中取一个词条;
|
||||
4. 若词条首次出现,顶部创建对应计数器;
|
||||
5. 后续同词条出现时对应计数器 +1;
|
||||
6. 播放敲击音效;
|
||||
7. 敲击物图案执行压缩、回弹或轻微震动动画;
|
||||
8. 木鱼上方飘出“词条+1”并淡出。
|
||||
|
||||
音频播放:
|
||||
|
||||
1. 前端使用小复音池;
|
||||
2. 设置最小播放间隔,避免极端连点导致浏览器抖动;
|
||||
3. 点击计数不能因为音频节流而丢失;
|
||||
4. 签名 URL 未就绪时先静音表现,不请求裸 generated 私有路径。
|
||||
|
||||
后端只保存 run 摘要,不保存每次点击的完整明细;`checkpoint` 和 `finish` 都写入总敲击次数与词条计数快照。
|
||||
|
||||
## 12. 公开链路
|
||||
|
||||
平台首页推荐、发现、公开详情、搜索、已玩作品和公开试玩统一按 `sourceType='wooden-fish'` 与 `WF-*` 公开作品号识别敲木鱼作品。
|
||||
|
||||
公开列表优先消费 `wooden_fish_gallery_card_view` 订阅缓存。公开详情如果卡片摘要不足以进入运行态,必须补读完整 work profile。
|
||||
|
||||
## 13. 验收
|
||||
|
||||
1. 创作入口能看到 `敲木鱼` 模板;
|
||||
2. 工作台可以填写敲击物描述、上传参考图、配置音效和祝福词;
|
||||
3. 提交后生成 image2 敲击物图案;
|
||||
4. 上传图不会直接进入运行态;
|
||||
5. 用户上传或录制音效时跳过音效生成并持久化该资产;
|
||||
6. 结果页能看到图案、试听音效、编辑祝福词并试玩;
|
||||
7. 运行态功能区点击不触发敲击;
|
||||
8. 非功能区点击会计数、播放音效、播放敲击动画并飘字;
|
||||
9. 顶部计数器只在词条首次出现时创建;
|
||||
10. 连点不丢计数;
|
||||
11. `checkpoint` 和 `finish` 只保存单次 run 摘要;
|
||||
12. 作品可以发布、进入公开列表和公开详情;
|
||||
13. `WF-*` 公开作品号能进入分享和运行态;
|
||||
14. `npm run check:encoding` 通过;
|
||||
15. schema 变更后 `npm run check:spacetime-schema` 通过。
|
||||
@@ -44,7 +44,7 @@ npm run check:server-rs-ddd
|
||||
|
||||
`server-rs/crates/spacetime-client/src/mapper.rs` 只作为聚合入口,负责声明 `src/mapper/` 下的领域子模块并 re-export 原有 record / mapper 能力;不要在该文件继续堆叠大段映射实现。
|
||||
|
||||
当前子模块按调用领域拆分:`assets.rs`、`auth.rs`、`runtime.rs`、`runtime_profile.rs`、`custom_world.rs`、`puzzle.rs`、`match3d.rs`、`square_hole.rs`、`visual_novel.rs`、`big_fish.rs`、`story.rs`、`ai.rs`、`bark_battle.rs`、`combat.rs`、`inventory.rs`、`npc.rs`,跨领域轻量 helper 和共享 record 统一放在 `common.rs`。该拆分只改变 `spacetime-client` 文件组织,不改变 SpacetimeDB schema、生成绑定、procedure result 契约或外部 DTO;后续新增 mapper 时优先落到对应领域子模块,不得重新引入跨层 JSON 字符串兼容结构。
|
||||
当前子模块按调用领域拆分:`assets.rs`、`auth.rs`、`runtime.rs`、`runtime_profile.rs`、`custom_world.rs`、`puzzle.rs`、`match3d.rs`、`jump_hop.rs`、`wooden_fish.rs`、`square_hole.rs`、`visual_novel.rs`、`big_fish.rs`、`story.rs`、`ai.rs`、`bark_battle.rs`、`combat.rs`、`inventory.rs`、`npc.rs`,跨领域轻量 helper 和共享 record 统一放在 `common.rs`。该拆分只改变 `spacetime-client` 文件组织,不改变 SpacetimeDB schema、生成绑定、procedure result 契约或外部 DTO;后续新增 mapper 时优先落到对应领域子模块,不得重新引入跨层 JSON 字符串兼容结构。
|
||||
|
||||
## API 路由分组
|
||||
|
||||
@@ -60,6 +60,7 @@ npm run check:server-rs-ddd
|
||||
- 自定义世界 / RPG:`/api/runtime/custom-world*`、`/api/story/*`、`/api/runtime/chat/*`。
|
||||
- 拼图:`/api/runtime/puzzle/*`。
|
||||
- 抓大鹅 Match3D:`/api/creation/match3d/*`、`/api/runtime/match3d/*`。
|
||||
- 敲木鱼:`/api/creation/wooden-fish/*`、`/api/runtime/wooden-fish/*`。
|
||||
- 方洞挑战:`/api/creation/square-hole/*`、`/api/runtime/square-hole/*`。
|
||||
- 视觉小说:`/api/creation/visual-novel/*`、`/api/runtime/visual-novel/*`。
|
||||
- 大鱼吃小鱼:`/api/runtime/big-fish/*`。
|
||||
@@ -156,7 +157,7 @@ npm run check:server-rs-ddd
|
||||
- Match3D 封面和 9:16 纯背景:VectorEngine `/v1/images/generations`。
|
||||
- Match3D 1:1 容器 UI:VectorEngine `/v1/images/edits` multipart 参考图。
|
||||
- Hyper3D / Rodin:只保留后端安全代理和旧数据兼容;新 Match3D 草稿和批量新增不再生成 GLB。
|
||||
- 音频:视觉小说专用音频路由保留;拼图和抓大鹅生成入口暂时关闭,通用 `/api/creation/audio/*` 对相关目标返回 `410 Gone`。
|
||||
- 音频:视觉小说专用音频路由保留;拼图和抓大鹅生成入口暂时关闭,通用 `/api/creation/audio/*` 对相关目标返回 `410 Gone`;敲木鱼 `hit_sound` 目标例外开放,复用 VectorEngine Vidu 音效生成、OSS 私有对象、`asset_object` 和 entity binding 链路,目标字段固定为 `entityKind='wooden_fish_work'`、`slot='hit_sound'`、`assetKind='wooden_fish_hit_sound'`、`storagePrefix='wooden_fish_assets'`。
|
||||
- OSS:私有 generated legacy path 进入浏览器前必须通过 `/api/assets/read-url` 换签;不要裸请求 `/generated-*`。
|
||||
|
||||
## SpacetimeDB 表目录
|
||||
@@ -396,6 +397,40 @@ npm run check:server-rs-ddd
|
||||
- 源码:`server-rs/crates/spacetime-module/src/jump_hop.rs`
|
||||
- 说明:跳一跳公开详情兼容投影,包含作品、路径和素材字段;公开列表主路径优先使用 `jump_hop_gallery_card_view`。
|
||||
|
||||
### `wooden_fish_agent_session`
|
||||
|
||||
- Rust 结构体:`WoodenFishAgentSessionRow`
|
||||
- 源码:`server-rs/crates/spacetime-module/src/wooden_fish/tables.rs`
|
||||
|
||||
### `wooden_fish_event`
|
||||
|
||||
- Rust 结构体:`WoodenFishEventRow`
|
||||
- 源码:`server-rs/crates/spacetime-module/src/wooden_fish/tables.rs`
|
||||
|
||||
### `wooden_fish_runtime_run`
|
||||
|
||||
- Rust 结构体:`WoodenFishRuntimeRunRow`
|
||||
- 源码:`server-rs/crates/spacetime-module/src/wooden_fish/tables.rs`
|
||||
|
||||
### `wooden_fish_work_profile`
|
||||
|
||||
- Rust 结构体:`WoodenFishWorkProfileRow`
|
||||
- 源码:`server-rs/crates/spacetime-module/src/wooden_fish/tables.rs`
|
||||
|
||||
### SpacetimeDB view:`wooden_fish_gallery_card_view`
|
||||
|
||||
- Rust view:`wooden_fish_gallery_card_view`
|
||||
- 返回类型:`Vec<WoodenFishGalleryCardViewRow>`
|
||||
- 源码:`server-rs/crates/spacetime-module/src/wooden_fish.rs`
|
||||
- 说明:敲木鱼公开广场列表卡片投影,只暴露 `publication_status = published` 的作品卡片字段;`api-server` 的 `spacetime-client` 长期订阅 `SELECT * FROM wooden_fish_gallery_card_view` 后,从本地 cache 构造敲木鱼公开列表响应。个人作品列表、详情、发布和运行态仍按 procedure 路径处理。
|
||||
|
||||
### SpacetimeDB view:`wooden_fish_gallery_view`
|
||||
|
||||
- Rust view:`wooden_fish_gallery_view`
|
||||
- 返回类型:`Vec<WoodenFishGalleryViewRow>`
|
||||
- 源码:`server-rs/crates/spacetime-module/src/wooden_fish.rs`
|
||||
- 说明:敲木鱼公开详情兼容投影,包含敲击物图案、敲击音效和飘字配置;公开列表主路径优先使用 `wooden_fish_gallery_card_view`。
|
||||
|
||||
### `match3d_agent_message`
|
||||
|
||||
- Rust 结构体:`Match3DAgentMessageRow`
|
||||
|
||||
@@ -87,6 +87,26 @@
|
||||
|
||||
平台首页推荐、精选、最新、公开详情、搜索、已玩作品和公开试玩统一按 `sourceType='jump-hop'` 与 `JH-*` 公开作品号识别跳一跳作品;从公开详情或推荐流启动运行态时,若卡片摘要不足以携带角色图、地块图集和路径配置,必须先补读完整 work profile 再传入运行态。
|
||||
|
||||
## 敲木鱼
|
||||
|
||||
对外名称:`敲木鱼`。工程域:`wooden-fish`。PRD 见 `docs/prd/【玩法创作】敲木鱼玩法模板PRD-2026-05-20.md`。
|
||||
|
||||
首版定位为单屏点击解压模板,链路对齐拼图的创作闭环:
|
||||
|
||||
```text
|
||||
创作入口 -> 工作台 -> 生成过程页 -> 结果页 -> 试玩 -> 发布 -> 运行态
|
||||
```
|
||||
|
||||
创作输入固定为:
|
||||
|
||||
1. `敲什么`:单图资产槽位。默认模板使用内置透明 PNG `/wooden-fish/default-hit-object.png` 作为 `bundled-default` 敲击物资产,避免默认关键词被重新语义化改形;用户输入自定义关键词或上传参考图时,后端必须使用 image2 生成最终敲击物图案,上传图只作为参考,不直接进入运行态。自定义 `compile-draft` / `regenerate-hit-object` 必须完成 image2 -> OSS 私有对象 -> asset object 登记和绑定后,再由 `api-server` 注入真实 `hitObjectAsset.imageSrc`,不能只写 `/generated-wooden-fish-assets/...` 占位路径,也不能接受前端请求自带的 `hitObjectAsset` 短路生成。
|
||||
2. `敲击音效`:音频资产槽位,支持描述生成、上传和麦克风录制,统一写回 `hitSoundAsset`。描述生成复用通用 `/api/creation/audio/sound-effect` 的 VectorEngine Vidu 音效生成、下载、OSS 私有对象、asset object 登记和 entity binding 链路;木鱼目标固定为 `entityKind='wooden_fish_work'`、`slot='hit_sound'`、`assetKind='wooden_fish_hit_sound'`、`storagePrefix='wooden_fish_assets'`,不得再返回 `410 Gone`,也不得由 `spacetime-client` 合成假音频路径。
|
||||
3. `功德有什么`:最多 8 条飘字,默认 `幸运、健康、财富、姻缘、幸福、事业、成功、功德`;创作态只保存词条名,运行态飘字展示时再追加 `+1`。
|
||||
|
||||
运行态规则真相以后端 run 摘要为准,前端只做点击低延迟表现、敲击动画、音频播放和飘字渲染。每次非功能区点击在当前 run 内累计 `totalTapCount` 和 `wordCounters`;计数不进入账号长期账本,不做排行榜。顶部计数器仅在词条首次出现时创建,后续同词条继续累加。
|
||||
|
||||
平台首页推荐、精选、最新、公开详情、搜索、已玩作品和公开试玩统一按 `sourceType='wooden-fish'` 与 `WF-*` 公开作品号识别敲木鱼作品;公开列表应走 `wooden_fish_gallery_card_view` 订阅缓存,公开详情或运行态启动时卡片摘要不足则补读完整 work profile。
|
||||
|
||||
## 抓大鹅 Match3D
|
||||
|
||||
对外名称:`抓大鹅`。工程域:`match3d`。
|
||||
|
||||
@@ -39,7 +39,12 @@ export interface PublishGeneratedAudioAssetRequest {
|
||||
slot: string;
|
||||
assetKind: string;
|
||||
profileId?: string | null;
|
||||
storagePrefix?: 'puzzle_assets' | 'match3d_assets' | 'custom_world_scenes' | null;
|
||||
storagePrefix?:
|
||||
| 'puzzle_assets'
|
||||
| 'match3d_assets'
|
||||
| 'wooden_fish_assets'
|
||||
| 'custom_world_scenes'
|
||||
| null;
|
||||
}
|
||||
|
||||
export interface GeneratedAudioAssetResponse {
|
||||
|
||||
@@ -5,3 +5,4 @@ export type * from './jumpHop';
|
||||
export type * from './puzzleCreativeTemplate';
|
||||
export type * from './visualNovel';
|
||||
export type * from './barkBattle';
|
||||
export type * from './woodenFish';
|
||||
|
||||
195
packages/shared/src/contracts/woodenFish.ts
Normal file
195
packages/shared/src/contracts/woodenFish.ts
Normal file
@@ -0,0 +1,195 @@
|
||||
export type WoodenFishGenerationStatus =
|
||||
| 'draft'
|
||||
| 'generating'
|
||||
| 'ready'
|
||||
| 'failed';
|
||||
|
||||
export type WoodenFishActionType =
|
||||
| 'compile-draft'
|
||||
| 'regenerate-hit-object'
|
||||
| 'generate-hit-sound'
|
||||
| 'replace-hit-sound'
|
||||
| 'update-work-meta'
|
||||
| 'update-floating-words';
|
||||
|
||||
export type WoodenFishRunStatus = 'playing' | 'finished';
|
||||
|
||||
export interface WoodenFishImageAsset {
|
||||
assetId: string;
|
||||
imageSrc: string;
|
||||
imageObjectKey: string;
|
||||
assetObjectId: string;
|
||||
generationProvider: string;
|
||||
prompt: string;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
export interface WoodenFishAudioAsset {
|
||||
assetId: string;
|
||||
audioSrc: string;
|
||||
audioObjectKey: string;
|
||||
assetObjectId: string;
|
||||
source: string;
|
||||
prompt?: string | null;
|
||||
durationMs?: number | null;
|
||||
}
|
||||
|
||||
export interface WoodenFishWorkspaceCreateRequest {
|
||||
templateId: string;
|
||||
workTitle: string;
|
||||
workDescription: string;
|
||||
themeTags: string[];
|
||||
hitObjectPrompt: string;
|
||||
hitObjectReferenceImageSrc?: string | null;
|
||||
hitSoundPrompt?: string | null;
|
||||
hitSoundAsset?: WoodenFishAudioAsset | null;
|
||||
floatingWords: string[];
|
||||
}
|
||||
|
||||
export interface WoodenFishActionRequest {
|
||||
actionType: WoodenFishActionType;
|
||||
profileId?: string | null;
|
||||
workTitle?: string | null;
|
||||
workDescription?: string | null;
|
||||
themeTags?: string[] | null;
|
||||
hitObjectPrompt?: string | null;
|
||||
hitObjectReferenceImageSrc?: string | null;
|
||||
hitSoundPrompt?: string | null;
|
||||
hitSoundAsset?: WoodenFishAudioAsset | null;
|
||||
floatingWords?: string[] | null;
|
||||
}
|
||||
|
||||
export interface WoodenFishWordCounter {
|
||||
text: string;
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface WoodenFishDraftResponse {
|
||||
templateId: string;
|
||||
templateName: string;
|
||||
profileId: string | null;
|
||||
workTitle: string;
|
||||
workDescription: string;
|
||||
themeTags: string[];
|
||||
hitObjectPrompt: string;
|
||||
hitObjectReferenceImageSrc: string | null;
|
||||
hitSoundPrompt: string | null;
|
||||
floatingWords: string[];
|
||||
hitObjectAsset: WoodenFishImageAsset | null;
|
||||
hitSoundAsset: WoodenFishAudioAsset | null;
|
||||
coverImageSrc: string | null;
|
||||
generationStatus: WoodenFishGenerationStatus;
|
||||
}
|
||||
|
||||
export interface WoodenFishSessionSnapshotResponse {
|
||||
sessionId: string;
|
||||
ownerUserId: string;
|
||||
status: WoodenFishGenerationStatus;
|
||||
draft: WoodenFishDraftResponse | null;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface WoodenFishSessionResponse {
|
||||
session: WoodenFishSessionSnapshotResponse;
|
||||
}
|
||||
|
||||
export interface WoodenFishActionResponse {
|
||||
actionType: WoodenFishActionType;
|
||||
session: WoodenFishSessionSnapshotResponse;
|
||||
work: WoodenFishWorkProfileResponse | null;
|
||||
}
|
||||
|
||||
export interface WoodenFishWorkSummaryResponse {
|
||||
runtimeKind: 'wooden-fish';
|
||||
workId: string;
|
||||
profileId: string;
|
||||
ownerUserId: string;
|
||||
sourceSessionId: string | null;
|
||||
workTitle: string;
|
||||
workDescription: string;
|
||||
themeTags: string[];
|
||||
coverImageSrc: string | null;
|
||||
publicationStatus: string;
|
||||
playCount: number;
|
||||
updatedAt: string;
|
||||
publishedAt: string | null;
|
||||
publishReady: boolean;
|
||||
generationStatus: WoodenFishGenerationStatus;
|
||||
}
|
||||
|
||||
export interface WoodenFishWorkProfileResponse {
|
||||
summary: WoodenFishWorkSummaryResponse;
|
||||
draft: WoodenFishDraftResponse;
|
||||
hitObjectAsset: WoodenFishImageAsset;
|
||||
hitSoundAsset: WoodenFishAudioAsset;
|
||||
floatingWords: string[];
|
||||
}
|
||||
|
||||
export interface WoodenFishWorkDetailResponse {
|
||||
item: WoodenFishWorkProfileResponse;
|
||||
}
|
||||
|
||||
export interface WoodenFishWorkMutationResponse {
|
||||
item: WoodenFishWorkProfileResponse;
|
||||
}
|
||||
|
||||
export interface WoodenFishGalleryCardResponse {
|
||||
publicWorkCode: string;
|
||||
workId: string;
|
||||
profileId: string;
|
||||
ownerUserId: string;
|
||||
authorDisplayName: string;
|
||||
workTitle: string;
|
||||
workDescription: string;
|
||||
coverImageSrc: string | null;
|
||||
themeTags: string[];
|
||||
publicationStatus: string;
|
||||
playCount: number;
|
||||
updatedAt: string;
|
||||
publishedAt: string | null;
|
||||
generationStatus: WoodenFishGenerationStatus;
|
||||
}
|
||||
|
||||
export interface WoodenFishGalleryResponse {
|
||||
items: WoodenFishGalleryCardResponse[];
|
||||
hasMore: boolean;
|
||||
nextCursor: string | null;
|
||||
}
|
||||
|
||||
export interface WoodenFishGalleryDetailResponse {
|
||||
item: WoodenFishWorkProfileResponse;
|
||||
}
|
||||
|
||||
export interface WoodenFishRuntimeRunSnapshotResponse {
|
||||
runId: string;
|
||||
profileId: string;
|
||||
ownerUserId: string;
|
||||
status: WoodenFishRunStatus;
|
||||
totalTapCount: number;
|
||||
wordCounters: WoodenFishWordCounter[];
|
||||
startedAtMs: number;
|
||||
updatedAtMs: number;
|
||||
finishedAtMs: number | null;
|
||||
}
|
||||
|
||||
export interface WoodenFishRunResponse {
|
||||
run: WoodenFishRuntimeRunSnapshotResponse;
|
||||
}
|
||||
|
||||
export interface WoodenFishStartRunRequest {
|
||||
profileId: string;
|
||||
}
|
||||
|
||||
export interface WoodenFishCheckpointRunRequest {
|
||||
totalTapCount: number;
|
||||
wordCounters: WoodenFishWordCounter[];
|
||||
clientEventId: string;
|
||||
}
|
||||
|
||||
export interface WoodenFishFinishRunRequest {
|
||||
totalTapCount: number;
|
||||
wordCounters: WoodenFishWordCounter[];
|
||||
clientEventId: string;
|
||||
}
|
||||
BIN
public/wooden-fish/default-hit-object.png
Normal file
BIN
public/wooden-fish/default-hit-object.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 562 KiB |
10
server-rs/Cargo.lock
generated
10
server-rs/Cargo.lock
generated
@@ -1947,6 +1947,14 @@ dependencies = [
|
||||
"spacetimedb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "module-wooden-fish"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"spacetimedb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "moxcms"
|
||||
version = "0.8.1"
|
||||
@@ -3278,6 +3286,7 @@ dependencies = [
|
||||
"module-square-hole",
|
||||
"module-story",
|
||||
"module-visual-novel",
|
||||
"module-wooden-fish",
|
||||
"opentelemetry",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -3311,6 +3320,7 @@ dependencies = [
|
||||
"module-runtime-item",
|
||||
"module-square-hole",
|
||||
"module-story",
|
||||
"module-wooden-fish",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
|
||||
@@ -18,6 +18,7 @@ members = [
|
||||
"crates/module-inventory",
|
||||
"crates/module-custom-world",
|
||||
"crates/module-jump-hop",
|
||||
"crates/module-wooden-fish",
|
||||
"crates/module-match3d",
|
||||
"crates/module-npc",
|
||||
"crates/module-puzzle",
|
||||
@@ -59,6 +60,7 @@ module-creative-agent = { path = "crates/module-creative-agent", default-feature
|
||||
module-custom-world = { path = "crates/module-custom-world", default-features = false }
|
||||
module-inventory = { path = "crates/module-inventory", default-features = false }
|
||||
module-jump-hop = { path = "crates/module-jump-hop", default-features = false }
|
||||
module-wooden-fish = { path = "crates/module-wooden-fish", default-features = false }
|
||||
module-match3d = { path = "crates/module-match3d", default-features = false }
|
||||
module-npc = { path = "crates/module-npc", default-features = false }
|
||||
module-progression = { path = "crates/module-progression", default-features = false }
|
||||
|
||||
@@ -60,6 +60,7 @@ pub fn build_router(state: AppState) -> Router {
|
||||
.merge(modules::match3d::router(state.clone()))
|
||||
.merge(modules::square_hole::router(state.clone()))
|
||||
.merge(modules::jump_hop::router(state.clone()))
|
||||
.merge(modules::wooden_fish::router(state.clone()))
|
||||
.merge(modules::puzzle::router(state.clone()))
|
||||
.merge(visual_novel_router(state.clone()))
|
||||
.route(
|
||||
|
||||
@@ -89,6 +89,7 @@ mod volcengine_speech;
|
||||
mod wechat_auth;
|
||||
mod wechat_pay;
|
||||
mod wechat_provider;
|
||||
mod wooden_fish;
|
||||
mod work_author;
|
||||
mod work_play_tracking;
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use super::*;
|
||||
#[cfg(test)]
|
||||
use crate::generated_asset_sheets::crop_generated_asset_sheet_view_edge_matte;
|
||||
use crate::generated_asset_sheets::{
|
||||
GeneratedAssetSheetPersistInput, GeneratedAssetSheetPersistPrompt,
|
||||
GeneratedAssetSheetPromptInput, GeneratedAssetSheetSliceImage,
|
||||
build_generated_asset_sheet_prompt, persist_generated_asset_sheet_bytes,
|
||||
slice_generated_asset_sheet,
|
||||
};
|
||||
#[cfg(test)]
|
||||
use crate::generated_asset_sheets::crop_generated_asset_sheet_view_edge_matte;
|
||||
|
||||
pub(super) async fn generate_match3d_item_assets(
|
||||
state: &AppState,
|
||||
|
||||
@@ -14,3 +14,4 @@ pub mod profile;
|
||||
pub mod puzzle;
|
||||
pub mod square_hole;
|
||||
pub mod story;
|
||||
pub mod wooden_fish;
|
||||
|
||||
80
server-rs/crates/api-server/src/modules/wooden_fish.rs
Normal file
80
server-rs/crates/api-server/src/modules/wooden_fish.rs
Normal file
@@ -0,0 +1,80 @@
|
||||
use axum::{
|
||||
Router, middleware,
|
||||
routing::{get, post},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
auth::require_bearer_auth,
|
||||
state::AppState,
|
||||
wooden_fish::{
|
||||
checkpoint_wooden_fish_run, create_wooden_fish_session, execute_wooden_fish_action,
|
||||
finish_wooden_fish_run, get_wooden_fish_gallery_detail, get_wooden_fish_runtime_work,
|
||||
get_wooden_fish_session, list_wooden_fish_gallery, publish_wooden_fish_work,
|
||||
start_wooden_fish_run,
|
||||
},
|
||||
};
|
||||
|
||||
pub fn router(state: AppState) -> Router<AppState> {
|
||||
Router::new()
|
||||
.route(
|
||||
"/api/creation/wooden-fish/sessions",
|
||||
post(create_wooden_fish_session).route_layer(middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
require_bearer_auth,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/api/creation/wooden-fish/sessions/{session_id}",
|
||||
get(get_wooden_fish_session).route_layer(middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
require_bearer_auth,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/api/creation/wooden-fish/sessions/{session_id}/actions",
|
||||
post(execute_wooden_fish_action).route_layer(middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
require_bearer_auth,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/api/creation/wooden-fish/works/{profile_id}/publish",
|
||||
post(publish_wooden_fish_work).route_layer(middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
require_bearer_auth,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/api/runtime/wooden-fish/works/{profile_id}",
|
||||
get(get_wooden_fish_runtime_work),
|
||||
)
|
||||
.route(
|
||||
"/api/runtime/wooden-fish/runs",
|
||||
post(start_wooden_fish_run).route_layer(middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
require_bearer_auth,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/api/runtime/wooden-fish/runs/{run_id}/checkpoint",
|
||||
post(checkpoint_wooden_fish_run).route_layer(middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
require_bearer_auth,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/api/runtime/wooden-fish/runs/{run_id}/finish",
|
||||
post(finish_wooden_fish_run).route_layer(middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
require_bearer_auth,
|
||||
)),
|
||||
)
|
||||
.route(
|
||||
"/api/runtime/wooden-fish/gallery",
|
||||
get(list_wooden_fish_gallery),
|
||||
)
|
||||
.route(
|
||||
"/api/runtime/wooden-fish/gallery/{public_work_code}",
|
||||
get(get_wooden_fish_gallery_detail),
|
||||
)
|
||||
}
|
||||
@@ -1258,9 +1258,7 @@ fn build_admin_runtime(
|
||||
#[cfg(debug_assertions)]
|
||||
fn is_missing_creation_entry_config_procedure(error: &SpacetimeClientError) -> bool {
|
||||
match error {
|
||||
SpacetimeClientError::Procedure(message) => {
|
||||
message.contains("No such procedure")
|
||||
}
|
||||
SpacetimeClientError::Procedure(message) => message.contains("No such procedure"),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,13 +233,15 @@ pub async fn create_visual_novel_sound_effect_task(
|
||||
}
|
||||
|
||||
pub async fn create_sound_effect_task(
|
||||
State(_state): State<AppState>,
|
||||
State(state): State<AppState>,
|
||||
axum::extract::Extension(request_context): axum::extract::Extension<RequestContext>,
|
||||
payload: Result<Json<creation_audio::CreateSoundEffectRequest>, JsonRejection>,
|
||||
) -> Result<Json<Value>, Response> {
|
||||
let _ = parse_json_payload(&request_context, payload)?;
|
||||
Err(creation_audio_generation_disabled_error()
|
||||
.into_response_with_context(Some(&request_context)))
|
||||
let Json(payload) = parse_json_payload(&request_context, payload)?;
|
||||
create_sound_effect_task_response(&state, payload.prompt, payload.duration, payload.seed)
|
||||
.await
|
||||
.map(|task| json_success_body(Some(&request_context), task))
|
||||
.map_err(|error| error.into_response_with_context(Some(&request_context)))
|
||||
}
|
||||
|
||||
pub(crate) async fn generate_sound_effect_asset_for_creation(
|
||||
@@ -518,15 +520,25 @@ pub async fn publish_background_music_asset(
|
||||
}
|
||||
|
||||
pub async fn publish_sound_effect_asset(
|
||||
State(_state): State<AppState>,
|
||||
Path(_task_id): Path<String>,
|
||||
State(state): State<AppState>,
|
||||
Path(task_id): Path<String>,
|
||||
axum::extract::Extension(request_context): axum::extract::Extension<RequestContext>,
|
||||
axum::extract::Extension(_authenticated): axum::extract::Extension<AuthenticatedAccessToken>,
|
||||
axum::extract::Extension(authenticated): axum::extract::Extension<AuthenticatedAccessToken>,
|
||||
payload: Result<Json<creation_audio::PublishGeneratedAudioAssetRequest>, JsonRejection>,
|
||||
) -> Result<Json<Value>, Response> {
|
||||
let payload = parse_json_payload(&request_context, payload)?.0;
|
||||
Err(creation_audio_generation_disabled_error_for_target(payload)
|
||||
.into_response_with_context(Some(&request_context)))
|
||||
let target = build_creation_audio_target(payload, AudioAssetSlot::SoundEffect)
|
||||
.map_err(|error| error.into_response_with_context(Some(&request_context)))?;
|
||||
publish_generated_audio_asset(
|
||||
&state,
|
||||
authenticated.claims().user_id(),
|
||||
task_id,
|
||||
AudioAssetSlot::SoundEffect,
|
||||
target,
|
||||
)
|
||||
.await
|
||||
.map(|payload| json_success_body(Some(&request_context), payload))
|
||||
.map_err(|error| error.into_response_with_context(Some(&request_context)))
|
||||
}
|
||||
|
||||
async fn publish_generated_audio_asset(
|
||||
@@ -860,10 +872,36 @@ fn build_visual_novel_audio_target(
|
||||
})
|
||||
}
|
||||
|
||||
fn build_creation_audio_target(
|
||||
payload: creation_audio::PublishGeneratedAudioAssetRequest,
|
||||
slot: AudioAssetSlot,
|
||||
) -> Result<AudioAssetBindingTarget, AppError> {
|
||||
if matches!(slot, AudioAssetSlot::SoundEffect)
|
||||
&& payload.entity_kind.trim() == "wooden_fish_work"
|
||||
&& payload.slot.trim() == "hit_sound"
|
||||
&& payload.asset_kind.trim() == "wooden_fish_hit_sound"
|
||||
&& payload.storage_prefix
|
||||
== Some(creation_audio::CreationAudioStoragePrefix::WoodenFishAssets)
|
||||
{
|
||||
let entity_id = normalize_limited_text(&payload.entity_id, "entityId", 160)?;
|
||||
return Ok(AudioAssetBindingTarget {
|
||||
storage_scope: payload.entity_kind.trim().to_string(),
|
||||
entity_kind: payload.entity_kind.trim().to_string(),
|
||||
entity_id,
|
||||
slot: payload.slot.trim().to_string(),
|
||||
asset_kind: payload.asset_kind.trim().to_string(),
|
||||
profile_id: normalize_optional_text(payload.profile_id.as_deref()),
|
||||
storage_prefix: LegacyAssetPrefix::WoodenFishAssets,
|
||||
});
|
||||
}
|
||||
|
||||
Err(creation_audio_generation_disabled_error_for_target(payload))
|
||||
}
|
||||
|
||||
fn creation_audio_generation_disabled_error() -> AppError {
|
||||
AppError::from_status(StatusCode::GONE).with_details(json!({
|
||||
"provider": VECTOR_ENGINE_PROVIDER,
|
||||
"message": "拼图与抓大鹅音频生成入口已临时关闭",
|
||||
"message": "当前创作音频目标未开放",
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -872,8 +910,9 @@ fn creation_audio_generation_disabled_error_for_target(
|
||||
) -> AppError {
|
||||
creation_audio_generation_disabled_error().with_details(json!({
|
||||
"provider": VECTOR_ENGINE_PROVIDER,
|
||||
"message": "拼图与抓大鹅音频生成入口已临时关闭",
|
||||
"message": "当前创作音频目标未开放",
|
||||
"entityKind": payload.entity_kind.trim(),
|
||||
"slot": payload.slot.trim(),
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -1434,7 +1473,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn disabled_creation_audio_targets_return_gone() {
|
||||
fn disabled_creation_audio_targets_return_gone_except_wooden_fish_sound_effects() {
|
||||
let payload = creation_audio::PublishGeneratedAudioAssetRequest {
|
||||
entity_kind: "puzzle_work".to_string(),
|
||||
entity_id: "puzzle-profile-1".to_string(),
|
||||
@@ -1467,6 +1506,22 @@ mod tests {
|
||||
};
|
||||
let error = creation_audio_generation_disabled_error_for_target(payload);
|
||||
assert_eq!(error.status_code(), StatusCode::GONE);
|
||||
|
||||
let payload = creation_audio::PublishGeneratedAudioAssetRequest {
|
||||
entity_kind: "wooden_fish_work".to_string(),
|
||||
entity_id: "wooden-fish-profile-1".to_string(),
|
||||
slot: "hit_sound".to_string(),
|
||||
asset_kind: "wooden_fish_hit_sound".to_string(),
|
||||
profile_id: Some("wooden-fish-profile-1".to_string()),
|
||||
storage_prefix: Some(creation_audio::CreationAudioStoragePrefix::WoodenFishAssets),
|
||||
};
|
||||
let target = build_creation_audio_target(payload, AudioAssetSlot::SoundEffect)
|
||||
.expect("wooden fish hit sound target should be enabled");
|
||||
|
||||
assert_eq!(target.entity_kind, "wooden_fish_work");
|
||||
assert_eq!(target.slot, "hit_sound");
|
||||
assert_eq!(target.storage_prefix, LegacyAssetPrefix::WoodenFishAssets);
|
||||
assert_eq!(target.storage_scope, "wooden_fish_work");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
1107
server-rs/crates/api-server/src/wooden_fish.rs
Normal file
1107
server-rs/crates/api-server/src/wooden_fish.rs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -348,15 +348,15 @@ mod tests {
|
||||
assert_eq!(perfect.status, JumpHopRunStatus::Playing);
|
||||
assert_eq!(perfect.current_platform_index, 1);
|
||||
|
||||
let hit = apply_jump(&run, perfect_charge.saturating_add(80), 200)
|
||||
.expect("jump should resolve");
|
||||
let hit =
|
||||
apply_jump(&run, perfect_charge.saturating_add(80), 200).expect("jump should resolve");
|
||||
assert_eq!(
|
||||
hit.last_jump.as_ref().unwrap().result,
|
||||
JumpHopJumpResultKind::Hit
|
||||
);
|
||||
|
||||
let miss = apply_jump(&run, perfect_charge.saturating_add(900), 200)
|
||||
.expect("jump should resolve");
|
||||
let miss =
|
||||
apply_jump(&run, perfect_charge.saturating_add(900), 200).expect("jump should resolve");
|
||||
assert_eq!(miss.status, JumpHopRunStatus::Failed);
|
||||
assert_eq!(
|
||||
miss.last_jump.as_ref().unwrap().result,
|
||||
|
||||
@@ -105,6 +105,17 @@ pub fn default_creation_entry_type_snapshots(
|
||||
45,
|
||||
updated_at_micros,
|
||||
),
|
||||
build_default_creation_entry_type_snapshot(
|
||||
"wooden-fish",
|
||||
"敲木鱼",
|
||||
"点击祈福轻玩法",
|
||||
"可创建",
|
||||
"/wooden-fish/default-hit-object.png",
|
||||
true,
|
||||
true,
|
||||
47,
|
||||
updated_at_micros,
|
||||
),
|
||||
build_default_creation_entry_type_snapshot(
|
||||
"square-hole",
|
||||
"方洞",
|
||||
|
||||
@@ -251,6 +251,25 @@ mod tests {
|
||||
assert_eq!(bark_battle.sort_order, 85);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_creation_entry_types_include_wooden_fish() {
|
||||
let configs = default_creation_entry_type_snapshots(1);
|
||||
let wooden_fish = configs
|
||||
.iter()
|
||||
.find(|item| item.id == "wooden-fish")
|
||||
.expect("wooden-fish creation entry should be seeded");
|
||||
|
||||
assert_eq!(wooden_fish.title, "敲木鱼");
|
||||
assert!(wooden_fish.visible);
|
||||
assert!(wooden_fish.open);
|
||||
assert_eq!(wooden_fish.badge, "可创建");
|
||||
assert_eq!(wooden_fish.sort_order, 47);
|
||||
assert_eq!(
|
||||
wooden_fish.image_src,
|
||||
"/wooden-fish/default-hit-object.png"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn normalized_clamps_music_volume_into_valid_range() {
|
||||
let low = RuntimeSettings::normalized(-1.0, RuntimePlatformTheme::Light);
|
||||
|
||||
13
server-rs/crates/module-wooden-fish/Cargo.toml
Normal file
13
server-rs/crates/module-wooden-fish/Cargo.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "module-wooden-fish"
|
||||
edition.workspace = true
|
||||
version.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[features]
|
||||
default = []
|
||||
spacetime-types = ["dep:spacetimedb"]
|
||||
|
||||
[dependencies]
|
||||
serde = { workspace = true }
|
||||
spacetimedb = { workspace = true, optional = true }
|
||||
4
server-rs/crates/module-wooden-fish/src/application.rs
Normal file
4
server-rs/crates/module-wooden-fish/src/application.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
pub use crate::domain::{
|
||||
apply_run_checkpoint, default_floating_words, finish_run, normalize_floating_words,
|
||||
normalize_word_counters,
|
||||
};
|
||||
8
server-rs/crates/module-wooden-fish/src/commands.rs
Normal file
8
server-rs/crates/module-wooden-fish/src/commands.rs
Normal file
@@ -0,0 +1,8 @@
|
||||
pub fn normalize_wooden_fish_prompt(value: &str, fallback: &str) -> String {
|
||||
let value = value.trim();
|
||||
if value.is_empty() {
|
||||
fallback.to_string()
|
||||
} else {
|
||||
value.to_string()
|
||||
}
|
||||
}
|
||||
281
server-rs/crates/module-wooden-fish/src/domain.rs
Normal file
281
server-rs/crates/module-wooden-fish/src/domain.rs
Normal file
@@ -0,0 +1,281 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
#[cfg(feature = "spacetime-types")]
|
||||
use spacetimedb::SpacetimeType;
|
||||
|
||||
pub const WOODEN_FISH_SESSION_ID_PREFIX: &str = "wooden-fish-session-";
|
||||
pub const WOODEN_FISH_PROFILE_ID_PREFIX: &str = "wooden-fish-profile-";
|
||||
pub const WOODEN_FISH_WORK_ID_PREFIX: &str = "wooden-fish-work-";
|
||||
pub const WOODEN_FISH_RUN_ID_PREFIX: &str = "wooden-fish-run-";
|
||||
|
||||
pub const DEFAULT_FLOATING_WORDS: [&str; 8] = [
|
||||
"幸运", "健康", "财富", "姻缘", "幸福", "事业", "成功", "功德",
|
||||
];
|
||||
|
||||
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum WoodenFishRunStatus {
|
||||
Playing,
|
||||
Finished,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct WoodenFishWordCounter {
|
||||
pub text: String,
|
||||
pub count: u32,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "spacetime-types", derive(SpacetimeType))]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct WoodenFishRunSnapshot {
|
||||
pub run_id: String,
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub status: WoodenFishRunStatus,
|
||||
pub total_tap_count: u32,
|
||||
pub word_counters: Vec<WoodenFishWordCounter>,
|
||||
pub started_at_ms: u64,
|
||||
pub updated_at_ms: u64,
|
||||
pub finished_at_ms: Option<u64>,
|
||||
}
|
||||
|
||||
pub fn default_floating_words() -> Vec<String> {
|
||||
DEFAULT_FLOATING_WORDS
|
||||
.iter()
|
||||
.map(|value| (*value).to_string())
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn normalize_floating_words(words: &[String]) -> Vec<String> {
|
||||
let mut normalized: Vec<String> = Vec::new();
|
||||
for word in words {
|
||||
let value = normalize_floating_word(word);
|
||||
if !value.is_empty() && !normalized.iter().any(|item| item == &value) {
|
||||
normalized.push(value);
|
||||
}
|
||||
if normalized.len() == 8 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if normalized.is_empty() {
|
||||
default_floating_words()
|
||||
} else {
|
||||
normalized
|
||||
}
|
||||
}
|
||||
|
||||
fn normalize_floating_word(word: &str) -> String {
|
||||
word.trim()
|
||||
.trim_end_matches(|ch: char| ch == '1' || ch.is_whitespace())
|
||||
.trim_end_matches(['+', '+'])
|
||||
.trim()
|
||||
.to_string()
|
||||
}
|
||||
|
||||
pub fn apply_run_checkpoint(
|
||||
current: &WoodenFishRunSnapshot,
|
||||
total_tap_count: u32,
|
||||
word_counters: Vec<WoodenFishWordCounter>,
|
||||
updated_at_ms: u64,
|
||||
) -> WoodenFishRunSnapshot {
|
||||
WoodenFishRunSnapshot {
|
||||
total_tap_count,
|
||||
word_counters: normalize_word_counters(word_counters),
|
||||
updated_at_ms,
|
||||
..current.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn finish_run(
|
||||
current: &WoodenFishRunSnapshot,
|
||||
total_tap_count: u32,
|
||||
word_counters: Vec<WoodenFishWordCounter>,
|
||||
finished_at_ms: u64,
|
||||
) -> WoodenFishRunSnapshot {
|
||||
WoodenFishRunSnapshot {
|
||||
status: WoodenFishRunStatus::Finished,
|
||||
total_tap_count,
|
||||
word_counters: normalize_word_counters(word_counters),
|
||||
updated_at_ms: finished_at_ms,
|
||||
finished_at_ms: Some(finished_at_ms),
|
||||
..current.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn normalize_word_counters(counters: Vec<WoodenFishWordCounter>) -> Vec<WoodenFishWordCounter> {
|
||||
let mut normalized: Vec<WoodenFishWordCounter> = Vec::new();
|
||||
for counter in counters {
|
||||
let text = normalize_floating_word(&counter.text);
|
||||
if text.is_empty() || counter.count == 0 {
|
||||
continue;
|
||||
}
|
||||
if let Some(existing) = normalized.iter_mut().find(|item| item.text == text) {
|
||||
existing.count = existing.count.saturating_add(counter.count);
|
||||
} else {
|
||||
normalized.push(WoodenFishWordCounter {
|
||||
text,
|
||||
count: counter.count,
|
||||
});
|
||||
}
|
||||
if normalized.len() == 8 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
normalized
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn floating_words_default_to_eight_blessing_entries() {
|
||||
assert_eq!(
|
||||
default_floating_words(),
|
||||
vec![
|
||||
"幸运".to_string(),
|
||||
"健康".to_string(),
|
||||
"财富".to_string(),
|
||||
"姻缘".to_string(),
|
||||
"幸福".to_string(),
|
||||
"事业".to_string(),
|
||||
"成功".to_string(),
|
||||
"功德".to_string(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn floating_words_are_trimmed_deduped_and_capped_at_eight() {
|
||||
let words = vec![
|
||||
" 幸运+1 ".to_string(),
|
||||
"幸运".to_string(),
|
||||
"健康".to_string(),
|
||||
"财富".to_string(),
|
||||
"姻缘".to_string(),
|
||||
"幸福".to_string(),
|
||||
"事业".to_string(),
|
||||
"成功".to_string(),
|
||||
"功德".to_string(),
|
||||
"快乐".to_string(),
|
||||
];
|
||||
|
||||
assert_eq!(normalize_floating_words(&words).len(), 8);
|
||||
assert_eq!(normalize_floating_words(&words)[0], "幸运");
|
||||
assert_eq!(normalize_floating_words(&words)[7], "功德");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn checkpoint_replaces_single_run_counter_snapshot() {
|
||||
let current = WoodenFishRunSnapshot {
|
||||
run_id: "wooden-fish-run-1".to_string(),
|
||||
profile_id: "wooden-fish-profile-1".to_string(),
|
||||
owner_user_id: "user-1".to_string(),
|
||||
status: WoodenFishRunStatus::Playing,
|
||||
total_tap_count: 0,
|
||||
word_counters: Vec::new(),
|
||||
started_at_ms: 100,
|
||||
updated_at_ms: 100,
|
||||
finished_at_ms: None,
|
||||
};
|
||||
|
||||
let next = apply_run_checkpoint(
|
||||
¤t,
|
||||
2,
|
||||
vec![WoodenFishWordCounter {
|
||||
text: "功德".to_string(),
|
||||
count: 2,
|
||||
}],
|
||||
160,
|
||||
);
|
||||
|
||||
assert_eq!(next.total_tap_count, 2);
|
||||
assert_eq!(next.word_counters[0].text, "功德");
|
||||
assert_eq!(next.updated_at_ms, 160);
|
||||
assert_eq!(next.started_at_ms, 100);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn word_counters_are_trimmed_deduped_and_capped_at_eight() {
|
||||
let counters = vec![
|
||||
WoodenFishWordCounter {
|
||||
text: " 幸运+1 ".to_string(),
|
||||
count: 1,
|
||||
},
|
||||
WoodenFishWordCounter {
|
||||
text: "幸运+1".to_string(),
|
||||
count: 2,
|
||||
},
|
||||
WoodenFishWordCounter {
|
||||
text: "健康+1".to_string(),
|
||||
count: 1,
|
||||
},
|
||||
WoodenFishWordCounter {
|
||||
text: "财富+1".to_string(),
|
||||
count: 1,
|
||||
},
|
||||
WoodenFishWordCounter {
|
||||
text: "姻缘+1".to_string(),
|
||||
count: 1,
|
||||
},
|
||||
WoodenFishWordCounter {
|
||||
text: "幸福+1".to_string(),
|
||||
count: 1,
|
||||
},
|
||||
WoodenFishWordCounter {
|
||||
text: "事业+1".to_string(),
|
||||
count: 1,
|
||||
},
|
||||
WoodenFishWordCounter {
|
||||
text: "成功+1".to_string(),
|
||||
count: 1,
|
||||
},
|
||||
WoodenFishWordCounter {
|
||||
text: "功德+1".to_string(),
|
||||
count: 1,
|
||||
},
|
||||
WoodenFishWordCounter {
|
||||
text: "快乐+1".to_string(),
|
||||
count: 1,
|
||||
},
|
||||
];
|
||||
|
||||
let normalized = normalize_word_counters(counters);
|
||||
|
||||
assert_eq!(normalized.len(), 8);
|
||||
assert_eq!(normalized[0].text, "幸运");
|
||||
assert_eq!(normalized[0].count, 3);
|
||||
assert_eq!(normalized[7].text, "功德");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn finish_run_sets_status_and_finished_timestamp() {
|
||||
let current = WoodenFishRunSnapshot {
|
||||
run_id: "wooden-fish-run-1".to_string(),
|
||||
profile_id: "wooden-fish-profile-1".to_string(),
|
||||
owner_user_id: "user-1".to_string(),
|
||||
status: WoodenFishRunStatus::Playing,
|
||||
total_tap_count: 3,
|
||||
word_counters: Vec::new(),
|
||||
started_at_ms: 100,
|
||||
updated_at_ms: 130,
|
||||
finished_at_ms: None,
|
||||
};
|
||||
|
||||
let next = finish_run(
|
||||
¤t,
|
||||
4,
|
||||
vec![WoodenFishWordCounter {
|
||||
text: "健康".to_string(),
|
||||
count: 4,
|
||||
}],
|
||||
220,
|
||||
);
|
||||
|
||||
assert_eq!(next.status, WoodenFishRunStatus::Finished);
|
||||
assert_eq!(next.total_tap_count, 4);
|
||||
assert_eq!(next.updated_at_ms, 220);
|
||||
assert_eq!(next.finished_at_ms, Some(220));
|
||||
assert_eq!(next.word_counters[0].text, "健康");
|
||||
}
|
||||
}
|
||||
23
server-rs/crates/module-wooden-fish/src/errors.rs
Normal file
23
server-rs/crates/module-wooden-fish/src/errors.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
use std::fmt::{self, Display};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum WoodenFishError {
|
||||
MissingRunId,
|
||||
MissingProfileId,
|
||||
MissingOwnerUserId,
|
||||
RunNotPlaying,
|
||||
}
|
||||
|
||||
impl Display for WoodenFishError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let message = match self {
|
||||
Self::MissingRunId => "缺少 runId",
|
||||
Self::MissingProfileId => "缺少 profileId",
|
||||
Self::MissingOwnerUserId => "owner_user_id 缺失",
|
||||
Self::RunNotPlaying => "当前运行态不是 playing",
|
||||
};
|
||||
write!(f, "{message}")
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for WoodenFishError {}
|
||||
25
server-rs/crates/module-wooden-fish/src/events.rs
Normal file
25
server-rs/crates/module-wooden-fish/src/events.rs
Normal file
@@ -0,0 +1,25 @@
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum WoodenFishDomainEvent {
|
||||
DraftCompiled {
|
||||
profile_id: String,
|
||||
owner_user_id: String,
|
||||
occurred_at_micros: i64,
|
||||
},
|
||||
WorkPublished {
|
||||
profile_id: String,
|
||||
owner_user_id: String,
|
||||
occurred_at_micros: i64,
|
||||
},
|
||||
RunCheckpointed {
|
||||
run_id: String,
|
||||
owner_user_id: String,
|
||||
total_tap_count: u32,
|
||||
occurred_at_micros: i64,
|
||||
},
|
||||
RunFinished {
|
||||
run_id: String,
|
||||
owner_user_id: String,
|
||||
total_tap_count: u32,
|
||||
occurred_at_micros: i64,
|
||||
},
|
||||
}
|
||||
11
server-rs/crates/module-wooden-fish/src/lib.rs
Normal file
11
server-rs/crates/module-wooden-fish/src/lib.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
mod application;
|
||||
mod commands;
|
||||
mod domain;
|
||||
mod errors;
|
||||
mod events;
|
||||
|
||||
pub use application::*;
|
||||
pub use commands::*;
|
||||
pub use domain::*;
|
||||
pub use errors::*;
|
||||
pub use events::*;
|
||||
@@ -20,12 +20,13 @@ const OSS_V4_REQUEST: &str = "aliyun_v4_request";
|
||||
const OSS_V4_SERVICE: &str = "oss";
|
||||
const OSS_UNSIGNED_PAYLOAD: &str = "UNSIGNED-PAYLOAD";
|
||||
|
||||
pub const LEGACY_PUBLIC_PREFIXES: [&str; 10] = [
|
||||
pub const LEGACY_PUBLIC_PREFIXES: [&str; 11] = [
|
||||
"generated-character-drafts",
|
||||
"generated-characters",
|
||||
"generated-animations",
|
||||
"generated-big-fish-assets",
|
||||
"generated-square-hole-assets",
|
||||
"generated-wooden-fish-assets",
|
||||
"generated-match3d-assets",
|
||||
"generated-puzzle-assets",
|
||||
"generated-custom-world-scenes",
|
||||
@@ -47,6 +48,7 @@ pub enum LegacyAssetPrefix {
|
||||
Animations,
|
||||
BigFishAssets,
|
||||
SquareHoleAssets,
|
||||
WoodenFishAssets,
|
||||
Match3DAssets,
|
||||
PuzzleAssets,
|
||||
CustomWorldScenes,
|
||||
@@ -234,6 +236,7 @@ impl LegacyAssetPrefix {
|
||||
"generated-animations" => Some(Self::Animations),
|
||||
"generated-big-fish-assets" => Some(Self::BigFishAssets),
|
||||
"generated-square-hole-assets" => Some(Self::SquareHoleAssets),
|
||||
"generated-wooden-fish-assets" => Some(Self::WoodenFishAssets),
|
||||
"generated-match3d-assets" => Some(Self::Match3DAssets),
|
||||
"generated-puzzle-assets" => Some(Self::PuzzleAssets),
|
||||
"generated-custom-world-scenes" => Some(Self::CustomWorldScenes),
|
||||
@@ -250,6 +253,7 @@ impl LegacyAssetPrefix {
|
||||
Self::Animations => "generated-animations",
|
||||
Self::BigFishAssets => "generated-big-fish-assets",
|
||||
Self::SquareHoleAssets => "generated-square-hole-assets",
|
||||
Self::WoodenFishAssets => "generated-wooden-fish-assets",
|
||||
Self::Match3DAssets => "generated-match3d-assets",
|
||||
Self::PuzzleAssets => "generated-puzzle-assets",
|
||||
Self::CustomWorldScenes => "generated-custom-world-scenes",
|
||||
@@ -1313,8 +1317,13 @@ mod tests {
|
||||
LegacyAssetPrefix::parse("/generated-match3d-assets/*"),
|
||||
Some(LegacyAssetPrefix::Match3DAssets)
|
||||
);
|
||||
assert_eq!(
|
||||
LegacyAssetPrefix::parse("/generated-wooden-fish-assets/*"),
|
||||
Some(LegacyAssetPrefix::WoodenFishAssets)
|
||||
);
|
||||
assert!(LEGACY_PUBLIC_PREFIXES.contains(&"generated-puzzle-assets"));
|
||||
assert!(LEGACY_PUBLIC_PREFIXES.contains(&"generated-match3d-assets"));
|
||||
assert!(LEGACY_PUBLIC_PREFIXES.contains(&"generated-wooden-fish-assets"));
|
||||
assert_eq!(LegacyAssetPrefix::parse("unknown"), None);
|
||||
}
|
||||
|
||||
@@ -1554,6 +1563,12 @@ mod tests {
|
||||
),
|
||||
Some(LegacyAssetPrefix::CustomWorldScenes)
|
||||
);
|
||||
assert_eq!(
|
||||
LegacyAssetPrefix::from_object_key(
|
||||
"generated-wooden-fish-assets/session/profile/hit_object/asset/image.png"
|
||||
),
|
||||
Some(LegacyAssetPrefix::WoodenFishAssets)
|
||||
);
|
||||
assert_eq!(
|
||||
LegacyAssetPrefix::from_object_key("workflow-cache/demo.json"),
|
||||
None
|
||||
|
||||
@@ -61,6 +61,7 @@ pub enum CreationAudioStoragePrefix {
|
||||
PuzzleAssets,
|
||||
#[serde(rename = "match3d_assets")]
|
||||
Match3DAssets,
|
||||
WoodenFishAssets,
|
||||
CustomWorldScenes,
|
||||
}
|
||||
|
||||
@@ -125,4 +126,20 @@ mod tests {
|
||||
assert_eq!(payload["taskId"], json!("task-1"));
|
||||
assert_eq!(payload["audioSrc"], json!("/generated-puzzle-assets/a.mp3"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn creation_audio_contracts_support_wooden_fish_storage_prefix() {
|
||||
let request = PublishGeneratedAudioAssetRequest {
|
||||
entity_kind: "wooden_fish_work".to_string(),
|
||||
entity_id: "wooden-fish-profile-1".to_string(),
|
||||
slot: "hit_sound".to_string(),
|
||||
asset_kind: "wooden_fish_hit_sound".to_string(),
|
||||
profile_id: Some("wooden-fish-profile-1".to_string()),
|
||||
storage_prefix: Some(CreationAudioStoragePrefix::WoodenFishAssets),
|
||||
};
|
||||
|
||||
let payload = serde_json::to_value(request).expect("request should serialize");
|
||||
|
||||
assert_eq!(payload["storagePrefix"], json!("wooden_fish_assets"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,3 +29,4 @@ pub mod square_hole_runtime;
|
||||
pub mod square_hole_works;
|
||||
pub mod story;
|
||||
pub mod visual_novel;
|
||||
pub mod wooden_fish;
|
||||
|
||||
485
server-rs/crates/shared-contracts/src/wooden_fish.rs
Normal file
485
server-rs/crates/shared-contracts/src/wooden_fish.rs
Normal file
@@ -0,0 +1,485 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum WoodenFishGenerationStatus {
|
||||
Draft,
|
||||
Generating,
|
||||
Ready,
|
||||
Failed,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum WoodenFishActionType {
|
||||
CompileDraft,
|
||||
RegenerateHitObject,
|
||||
GenerateHitSound,
|
||||
ReplaceHitSound,
|
||||
UpdateWorkMeta,
|
||||
UpdateFloatingWords,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum WoodenFishRunStatus {
|
||||
Playing,
|
||||
Finished,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishImageAsset {
|
||||
pub asset_id: String,
|
||||
pub image_src: String,
|
||||
pub image_object_key: String,
|
||||
pub asset_object_id: String,
|
||||
pub generation_provider: String,
|
||||
pub prompt: String,
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishAudioAsset {
|
||||
pub asset_id: String,
|
||||
pub audio_src: String,
|
||||
pub audio_object_key: String,
|
||||
pub asset_object_id: String,
|
||||
pub source: String,
|
||||
#[serde(default)]
|
||||
pub prompt: Option<String>,
|
||||
#[serde(default)]
|
||||
pub duration_ms: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishWorkspaceCreateRequest {
|
||||
pub template_id: String,
|
||||
pub work_title: String,
|
||||
pub work_description: String,
|
||||
pub theme_tags: Vec<String>,
|
||||
pub hit_object_prompt: String,
|
||||
#[serde(default)]
|
||||
pub hit_object_reference_image_src: Option<String>,
|
||||
#[serde(default)]
|
||||
pub hit_sound_prompt: Option<String>,
|
||||
#[serde(default)]
|
||||
pub hit_sound_asset: Option<WoodenFishAudioAsset>,
|
||||
pub floating_words: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishActionRequest {
|
||||
pub action_type: WoodenFishActionType,
|
||||
#[serde(default, skip_deserializing)]
|
||||
pub profile_id: Option<String>,
|
||||
#[serde(default)]
|
||||
pub work_title: Option<String>,
|
||||
#[serde(default)]
|
||||
pub work_description: Option<String>,
|
||||
#[serde(default)]
|
||||
pub theme_tags: Option<Vec<String>>,
|
||||
#[serde(default)]
|
||||
pub hit_object_prompt: Option<String>,
|
||||
#[serde(default)]
|
||||
pub hit_object_reference_image_src: Option<String>,
|
||||
#[serde(default, skip_deserializing)]
|
||||
pub hit_object_asset: Option<WoodenFishImageAsset>,
|
||||
#[serde(default)]
|
||||
pub hit_sound_prompt: Option<String>,
|
||||
#[serde(default)]
|
||||
pub hit_sound_asset: Option<WoodenFishAudioAsset>,
|
||||
#[serde(default)]
|
||||
pub floating_words: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishWordCounter {
|
||||
pub text: String,
|
||||
pub count: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishDraftResponse {
|
||||
pub template_id: String,
|
||||
pub template_name: String,
|
||||
#[serde(default)]
|
||||
pub profile_id: Option<String>,
|
||||
pub work_title: String,
|
||||
pub work_description: String,
|
||||
pub theme_tags: Vec<String>,
|
||||
pub hit_object_prompt: String,
|
||||
#[serde(default)]
|
||||
pub hit_object_reference_image_src: Option<String>,
|
||||
#[serde(default)]
|
||||
pub hit_sound_prompt: Option<String>,
|
||||
pub floating_words: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub hit_object_asset: Option<WoodenFishImageAsset>,
|
||||
#[serde(default)]
|
||||
pub hit_sound_asset: Option<WoodenFishAudioAsset>,
|
||||
#[serde(default)]
|
||||
pub cover_image_src: Option<String>,
|
||||
pub generation_status: WoodenFishGenerationStatus,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishSessionSnapshotResponse {
|
||||
pub session_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub status: WoodenFishGenerationStatus,
|
||||
#[serde(default)]
|
||||
pub draft: Option<WoodenFishDraftResponse>,
|
||||
pub created_at: String,
|
||||
pub updated_at: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishSessionResponse {
|
||||
pub session: WoodenFishSessionSnapshotResponse,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishActionResponse {
|
||||
pub action_type: WoodenFishActionType,
|
||||
pub session: WoodenFishSessionSnapshotResponse,
|
||||
#[serde(default)]
|
||||
pub work: Option<WoodenFishWorkProfileResponse>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishWorkSummaryResponse {
|
||||
pub runtime_kind: String,
|
||||
pub work_id: String,
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
#[serde(default)]
|
||||
pub source_session_id: Option<String>,
|
||||
pub work_title: String,
|
||||
pub work_description: String,
|
||||
pub theme_tags: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub cover_image_src: Option<String>,
|
||||
pub publication_status: String,
|
||||
pub play_count: u32,
|
||||
pub updated_at: String,
|
||||
#[serde(default)]
|
||||
pub published_at: Option<String>,
|
||||
pub publish_ready: bool,
|
||||
pub generation_status: WoodenFishGenerationStatus,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishWorkProfileResponse {
|
||||
pub summary: WoodenFishWorkSummaryResponse,
|
||||
pub draft: WoodenFishDraftResponse,
|
||||
pub hit_object_asset: WoodenFishImageAsset,
|
||||
pub hit_sound_asset: WoodenFishAudioAsset,
|
||||
pub floating_words: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishWorkDetailResponse {
|
||||
pub item: WoodenFishWorkProfileResponse,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishWorkMutationResponse {
|
||||
pub item: WoodenFishWorkProfileResponse,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishGalleryCardResponse {
|
||||
pub public_work_code: String,
|
||||
pub work_id: String,
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub author_display_name: String,
|
||||
pub work_title: String,
|
||||
pub work_description: String,
|
||||
#[serde(default)]
|
||||
pub cover_image_src: Option<String>,
|
||||
pub theme_tags: Vec<String>,
|
||||
pub publication_status: String,
|
||||
pub play_count: u32,
|
||||
pub updated_at: String,
|
||||
#[serde(default)]
|
||||
pub published_at: Option<String>,
|
||||
pub generation_status: WoodenFishGenerationStatus,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishGalleryResponse {
|
||||
pub items: Vec<WoodenFishGalleryCardResponse>,
|
||||
pub has_more: bool,
|
||||
#[serde(default)]
|
||||
pub next_cursor: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishGalleryDetailResponse {
|
||||
pub item: WoodenFishWorkProfileResponse,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishRuntimeRunSnapshotResponse {
|
||||
pub run_id: String,
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub status: WoodenFishRunStatus,
|
||||
pub total_tap_count: u32,
|
||||
pub word_counters: Vec<WoodenFishWordCounter>,
|
||||
pub started_at_ms: u64,
|
||||
pub updated_at_ms: u64,
|
||||
#[serde(default)]
|
||||
pub finished_at_ms: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishRunResponse {
|
||||
pub run: WoodenFishRuntimeRunSnapshotResponse,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishStartRunRequest {
|
||||
pub profile_id: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishCheckpointRunRequest {
|
||||
pub total_tap_count: u32,
|
||||
pub word_counters: Vec<WoodenFishWordCounter>,
|
||||
pub client_event_id: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishFinishRunRequest {
|
||||
pub total_tap_count: u32,
|
||||
pub word_counters: Vec<WoodenFishWordCounter>,
|
||||
pub client_event_id: String,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde_json::json;
|
||||
|
||||
#[test]
|
||||
fn wooden_fish_workspace_request_uses_camel_case_and_default_words() {
|
||||
let payload = serde_json::to_value(WoodenFishWorkspaceCreateRequest {
|
||||
template_id: "wooden-fish".to_string(),
|
||||
work_title: "今日敲木鱼".to_string(),
|
||||
work_description: "轻松敲击".to_string(),
|
||||
theme_tags: vec!["休闲".to_string()],
|
||||
hit_object_prompt: "卡通木鱼".to_string(),
|
||||
hit_object_reference_image_src: None,
|
||||
hit_sound_prompt: Some("清脆木鱼声".to_string()),
|
||||
hit_sound_asset: None,
|
||||
floating_words: vec![
|
||||
"幸运".to_string(),
|
||||
"健康".to_string(),
|
||||
"财富".to_string(),
|
||||
"姻缘".to_string(),
|
||||
"幸福".to_string(),
|
||||
"事业".to_string(),
|
||||
"成功".to_string(),
|
||||
"功德".to_string(),
|
||||
],
|
||||
})
|
||||
.expect("payload should serialize");
|
||||
|
||||
assert_eq!(payload["templateId"], json!("wooden-fish"));
|
||||
assert_eq!(payload["hitObjectPrompt"], json!("卡通木鱼"));
|
||||
assert_eq!(payload["hitSoundPrompt"], json!("清脆木鱼声"));
|
||||
assert_eq!(payload["floatingWords"][7], json!("功德"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn wooden_fish_runtime_snapshot_counts_words_inside_one_run() {
|
||||
let payload = serde_json::to_value(WoodenFishRuntimeRunSnapshotResponse {
|
||||
run_id: "wooden-fish-run-1".to_string(),
|
||||
profile_id: "wooden-fish-profile-1".to_string(),
|
||||
owner_user_id: "user-1".to_string(),
|
||||
status: WoodenFishRunStatus::Playing,
|
||||
total_tap_count: 3,
|
||||
word_counters: vec![
|
||||
WoodenFishWordCounter {
|
||||
text: "幸运".to_string(),
|
||||
count: 2,
|
||||
},
|
||||
WoodenFishWordCounter {
|
||||
text: "功德".to_string(),
|
||||
count: 1,
|
||||
},
|
||||
],
|
||||
started_at_ms: 100,
|
||||
updated_at_ms: 130,
|
||||
finished_at_ms: None,
|
||||
})
|
||||
.expect("payload should serialize");
|
||||
|
||||
assert_eq!(payload["status"], json!("playing"));
|
||||
assert_eq!(payload["totalTapCount"], json!(3));
|
||||
assert_eq!(payload["wordCounters"][0]["text"], json!("幸运"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn wooden_fish_action_request_serializes_audio_and_image_fields() {
|
||||
let payload = serde_json::to_value(WoodenFishActionRequest {
|
||||
action_type: WoodenFishActionType::ReplaceHitSound,
|
||||
profile_id: Some("wooden-fish-profile-1".to_string()),
|
||||
work_title: None,
|
||||
work_description: None,
|
||||
theme_tags: None,
|
||||
hit_object_prompt: Some("卡通铜钹".to_string()),
|
||||
hit_object_reference_image_src: Some("/uploads/reference.png".to_string()),
|
||||
hit_object_asset: Some(WoodenFishImageAsset {
|
||||
asset_id: "image-1".to_string(),
|
||||
image_src: "/generated-wooden-fish-assets/profile/hit-object/image.png".to_string(),
|
||||
image_object_key: "generated-wooden-fish-assets/profile/hit-object/image.png"
|
||||
.to_string(),
|
||||
asset_object_id: "image-object-1".to_string(),
|
||||
generation_provider: "image2".to_string(),
|
||||
prompt: "卡通铜钹".to_string(),
|
||||
width: 1024,
|
||||
height: 1024,
|
||||
}),
|
||||
hit_sound_prompt: Some("短促木鱼声".to_string()),
|
||||
hit_sound_asset: Some(WoodenFishAudioAsset {
|
||||
asset_id: "sound-1".to_string(),
|
||||
audio_src: "/generated/wooden-fish.mp3".to_string(),
|
||||
audio_object_key: "generated/wooden-fish.mp3".to_string(),
|
||||
asset_object_id: "asset-object-1".to_string(),
|
||||
source: "upload".to_string(),
|
||||
prompt: None,
|
||||
duration_ms: Some(800),
|
||||
}),
|
||||
floating_words: Some(vec!["功德".to_string()]),
|
||||
})
|
||||
.expect("payload should serialize");
|
||||
|
||||
assert_eq!(payload["actionType"], json!("replace-hit-sound"));
|
||||
assert_eq!(payload["profileId"], json!("wooden-fish-profile-1"));
|
||||
assert_eq!(payload["hitObjectPrompt"], json!("卡通铜钹"));
|
||||
assert_eq!(
|
||||
payload["hitObjectAsset"]["imageObjectKey"],
|
||||
json!("generated-wooden-fish-assets/profile/hit-object/image.png")
|
||||
);
|
||||
assert_eq!(payload["hitSoundAsset"]["source"], json!("upload"));
|
||||
assert_eq!(payload["hitSoundAsset"]["durationMs"], json!(800));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn wooden_fish_action_request_ignores_client_hit_object_asset() {
|
||||
let payload = serde_json::from_value::<WoodenFishActionRequest>(json!({
|
||||
"actionType": "compile-draft",
|
||||
"hitObjectPrompt": "卡通铜钹",
|
||||
"hitObjectAsset": {
|
||||
"assetId": "client-image",
|
||||
"imageSrc": "/generated-wooden-fish-assets/client/image.png",
|
||||
"imageObjectKey": "generated-wooden-fish-assets/client/image.png",
|
||||
"assetObjectId": "client-asset-object",
|
||||
"generationProvider": "client",
|
||||
"prompt": "跳过生成",
|
||||
"width": 1024,
|
||||
"height": 1024
|
||||
}
|
||||
}))
|
||||
.expect("payload should deserialize");
|
||||
|
||||
assert_eq!(payload.action_type, WoodenFishActionType::CompileDraft);
|
||||
assert_eq!(payload.hit_object_prompt.as_deref(), Some("卡通铜钹"));
|
||||
assert_eq!(payload.hit_object_asset, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn wooden_fish_work_profile_keeps_summary_and_runtime_assets() {
|
||||
let image = WoodenFishImageAsset {
|
||||
asset_id: "image-1".to_string(),
|
||||
image_src: "/generated/wooden-fish.png".to_string(),
|
||||
image_object_key: "generated/wooden-fish.png".to_string(),
|
||||
asset_object_id: "image-object-1".to_string(),
|
||||
generation_provider: "image2".to_string(),
|
||||
prompt: "卡通木鱼".to_string(),
|
||||
width: 1024,
|
||||
height: 1024,
|
||||
};
|
||||
let audio = WoodenFishAudioAsset {
|
||||
asset_id: "sound-1".to_string(),
|
||||
audio_src: "/generated/wooden-fish.mp3".to_string(),
|
||||
audio_object_key: "generated/wooden-fish.mp3".to_string(),
|
||||
asset_object_id: "sound-object-1".to_string(),
|
||||
source: "generated".to_string(),
|
||||
prompt: Some("清脆木鱼".to_string()),
|
||||
duration_ms: Some(600),
|
||||
};
|
||||
let profile = WoodenFishWorkProfileResponse {
|
||||
summary: WoodenFishWorkSummaryResponse {
|
||||
runtime_kind: "wooden-fish".to_string(),
|
||||
work_id: "wooden-fish-profile-1".to_string(),
|
||||
profile_id: "wooden-fish-profile-1".to_string(),
|
||||
owner_user_id: "user-1".to_string(),
|
||||
source_session_id: Some("wooden-fish-session-1".to_string()),
|
||||
work_title: "敲木鱼".to_string(),
|
||||
work_description: String::new(),
|
||||
theme_tags: vec!["休闲".to_string()],
|
||||
cover_image_src: Some(image.image_src.clone()),
|
||||
publication_status: "draft".to_string(),
|
||||
play_count: 0,
|
||||
updated_at: "2026-05-20T00:00:00Z".to_string(),
|
||||
published_at: None,
|
||||
publish_ready: true,
|
||||
generation_status: WoodenFishGenerationStatus::Ready,
|
||||
},
|
||||
draft: WoodenFishDraftResponse {
|
||||
template_id: "wooden-fish".to_string(),
|
||||
template_name: "敲木鱼".to_string(),
|
||||
profile_id: Some("wooden-fish-profile-1".to_string()),
|
||||
work_title: "敲木鱼".to_string(),
|
||||
work_description: String::new(),
|
||||
theme_tags: vec!["休闲".to_string()],
|
||||
hit_object_prompt: "卡通木鱼".to_string(),
|
||||
hit_object_reference_image_src: None,
|
||||
hit_sound_prompt: Some("清脆木鱼".to_string()),
|
||||
floating_words: vec!["功德".to_string()],
|
||||
hit_object_asset: Some(image.clone()),
|
||||
hit_sound_asset: Some(audio.clone()),
|
||||
cover_image_src: Some(image.image_src.clone()),
|
||||
generation_status: WoodenFishGenerationStatus::Ready,
|
||||
},
|
||||
hit_object_asset: image,
|
||||
hit_sound_asset: audio,
|
||||
floating_words: vec!["功德".to_string()],
|
||||
};
|
||||
|
||||
let payload = serde_json::to_value(profile).expect("profile should serialize");
|
||||
|
||||
assert_eq!(payload["summary"]["runtimeKind"], json!("wooden-fish"));
|
||||
assert_eq!(
|
||||
payload["hitObjectAsset"]["generationProvider"],
|
||||
json!("image2")
|
||||
);
|
||||
assert_eq!(payload["hitSoundAsset"]["source"], json!("generated"));
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,7 @@ use opentelemetry::{KeyValue, global, trace::TracerProvider};
|
||||
use opentelemetry_appender_tracing::layer::OpenTelemetryTracingBridge;
|
||||
use opentelemetry_otlp::WithExportConfig;
|
||||
use opentelemetry_sdk::{
|
||||
Resource,
|
||||
logs::SdkLoggerProvider,
|
||||
metrics::SdkMeterProvider,
|
||||
trace::SdkTracerProvider,
|
||||
Resource, logs::SdkLoggerProvider, metrics::SdkMeterProvider, trace::SdkTracerProvider,
|
||||
};
|
||||
use tracing::warn;
|
||||
use tracing_subscriber::{
|
||||
@@ -54,9 +51,7 @@ pub fn init_tracing(default_filter: &str, otel_config: OtelConfig) -> Result<(),
|
||||
tracing_opentelemetry::layer()
|
||||
.with_tracer(otel.tracer_provider.tracer("genarrative-api")),
|
||||
)
|
||||
.with(
|
||||
OpenTelemetryTracingBridge::new(&otel.logger_provider).with_filter(LevelFilter::INFO),
|
||||
)
|
||||
.with(OpenTelemetryTracingBridge::new(&otel.logger_provider).with_filter(LevelFilter::INFO))
|
||||
.try_init()
|
||||
.map_err(|error| io::Error::other(format!("初始化 tracing subscriber 失败:{error}")))
|
||||
}
|
||||
@@ -127,10 +122,12 @@ fn build_otel_pipeline() -> Option<OtelPipeline> {
|
||||
.with_periodic_exporter(metric_exporter)
|
||||
.build();
|
||||
let logger_provider = SdkLoggerProvider::builder()
|
||||
.with_resource(Resource::builder()
|
||||
.with_resource(
|
||||
Resource::builder()
|
||||
.with_service_name(read_env_or_default("OTEL_SERVICE_NAME", "genarrative-api"))
|
||||
.with_attribute(KeyValue::new("service.namespace", "genarrative"))
|
||||
.build())
|
||||
.build(),
|
||||
)
|
||||
.with_batch_exporter(log_exporter)
|
||||
.build();
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ module-combat = { workspace = true }
|
||||
module-custom-world = { workspace = true }
|
||||
module-inventory = { workspace = true }
|
||||
module-jump-hop = { workspace = true }
|
||||
module-wooden-fish = { workspace = true }
|
||||
module-match3d = { workspace = true }
|
||||
module-npc = { workspace = true }
|
||||
module-puzzle = { workspace = true }
|
||||
|
||||
@@ -5,11 +5,11 @@ use crate::mapper::{
|
||||
map_jump_hop_works_procedure_result,
|
||||
};
|
||||
use shared_contracts::jump_hop::{
|
||||
JumpHopActionRequest, JumpHopActionResponse, JumpHopActionType, JumpHopCharacterAsset, JumpHopDifficulty,
|
||||
JumpHopDraftResponse, JumpHopGalleryResponse, JumpHopGenerationStatus, JumpHopJumpRequest,
|
||||
JumpHopRestartRunRequest, JumpHopRuntimeRunSnapshotResponse, JumpHopSessionSnapshotResponse,
|
||||
JumpHopStartRunRequest, JumpHopStylePreset, JumpHopTileAsset, JumpHopTileType,
|
||||
JumpHopWorkProfileResponse,
|
||||
JumpHopActionRequest, JumpHopActionResponse, JumpHopActionType, JumpHopCharacterAsset,
|
||||
JumpHopDifficulty, JumpHopDraftResponse, JumpHopGalleryResponse, JumpHopGenerationStatus,
|
||||
JumpHopJumpRequest, JumpHopRestartRunRequest, JumpHopRuntimeRunSnapshotResponse,
|
||||
JumpHopSessionSnapshotResponse, JumpHopStartRunRequest, JumpHopStylePreset, JumpHopTileAsset,
|
||||
JumpHopTileType, JumpHopWorkProfileResponse,
|
||||
};
|
||||
use shared_kernel::build_prefixed_uuid_id;
|
||||
|
||||
@@ -21,10 +21,9 @@ impl SpacetimeClient {
|
||||
&self,
|
||||
session: JumpHopSessionSnapshotResponse,
|
||||
) -> Result<JumpHopSessionSnapshotResponse, SpacetimeClientError> {
|
||||
let draft = session
|
||||
.draft
|
||||
.clone()
|
||||
.ok_or_else(|| SpacetimeClientError::validation_failed("jump-hop session 缺少 draft"))?;
|
||||
let draft = session.draft.clone().ok_or_else(|| {
|
||||
SpacetimeClientError::validation_failed("jump-hop session 缺少 draft")
|
||||
})?;
|
||||
let theme_tags_json = Some(json_string(&draft.theme_tags)?);
|
||||
let config_json = Some(build_config_json(&draft)?);
|
||||
let work_title = draft.work_title.clone();
|
||||
@@ -164,15 +163,14 @@ impl SpacetimeClient {
|
||||
procedure_input: JumpHopWorkUpdateInput,
|
||||
) -> Result<JumpHopWorkProfileResponse, SpacetimeClientError> {
|
||||
self.call_after_connect("update_jump_hop_work", move |connection, sender| {
|
||||
connection.procedures().update_jump_hop_work_then(
|
||||
procedure_input,
|
||||
move |_, result| {
|
||||
connection
|
||||
.procedures()
|
||||
.update_jump_hop_work_then(procedure_input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(SpacetimeClientError::from_sdk_error)
|
||||
.and_then(map_jump_hop_work_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
},
|
||||
);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
@@ -212,15 +210,14 @@ impl SpacetimeClient {
|
||||
};
|
||||
|
||||
self.call_after_connect("list_jump_hop_works", move |connection, sender| {
|
||||
connection.procedures().list_jump_hop_works_then(
|
||||
procedure_input,
|
||||
move |_, result| {
|
||||
connection
|
||||
.procedures()
|
||||
.list_jump_hop_works_then(procedure_input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(SpacetimeClientError::from_sdk_error)
|
||||
.and_then(map_jump_hop_works_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
},
|
||||
);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
@@ -229,7 +226,8 @@ impl SpacetimeClient {
|
||||
&self,
|
||||
profile_id: String,
|
||||
) -> Result<JumpHopWorkProfileResponse, SpacetimeClientError> {
|
||||
self.get_jump_hop_work_profile(profile_id, String::new()).await
|
||||
self.get_jump_hop_work_profile(profile_id, String::new())
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn start_jump_hop_run(
|
||||
@@ -253,15 +251,14 @@ impl SpacetimeClient {
|
||||
procedure_input: JumpHopRunStartInput,
|
||||
) -> Result<JumpHopRuntimeRunSnapshotResponse, SpacetimeClientError> {
|
||||
self.call_after_connect("start_jump_hop_run", move |connection, sender| {
|
||||
connection.procedures().start_jump_hop_run_then(
|
||||
procedure_input,
|
||||
move |_, result| {
|
||||
connection
|
||||
.procedures()
|
||||
.start_jump_hop_run_then(procedure_input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(SpacetimeClientError::from_sdk_error)
|
||||
.and_then(map_jump_hop_run_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
},
|
||||
);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
@@ -277,15 +274,14 @@ impl SpacetimeClient {
|
||||
};
|
||||
|
||||
self.call_after_connect("get_jump_hop_run", move |connection, sender| {
|
||||
connection.procedures().get_jump_hop_run_then(
|
||||
procedure_input,
|
||||
move |_, result| {
|
||||
connection
|
||||
.procedures()
|
||||
.get_jump_hop_run_then(procedure_input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(SpacetimeClientError::from_sdk_error)
|
||||
.and_then(map_jump_hop_run_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
},
|
||||
);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
@@ -305,15 +301,14 @@ impl SpacetimeClient {
|
||||
};
|
||||
|
||||
self.call_after_connect("jump_hop_jump", move |connection, sender| {
|
||||
connection.procedures().jump_hop_jump_then(
|
||||
procedure_input,
|
||||
move |_, result| {
|
||||
connection
|
||||
.procedures()
|
||||
.jump_hop_jump_then(procedure_input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(SpacetimeClientError::from_sdk_error)
|
||||
.and_then(map_jump_hop_run_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
},
|
||||
);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
@@ -333,15 +328,14 @@ impl SpacetimeClient {
|
||||
};
|
||||
|
||||
self.call_after_connect("restart_jump_hop_run", move |connection, sender| {
|
||||
connection.procedures().restart_jump_hop_run_then(
|
||||
procedure_input,
|
||||
move |_, result| {
|
||||
connection
|
||||
.procedures()
|
||||
.restart_jump_hop_run_then(procedure_input, move |_, result| {
|
||||
let mapped = result
|
||||
.map_err(SpacetimeClientError::from_sdk_error)
|
||||
.and_then(map_jump_hop_run_procedure_result);
|
||||
send_once(&sender, mapped);
|
||||
},
|
||||
);
|
||||
});
|
||||
})
|
||||
.await
|
||||
}
|
||||
@@ -430,16 +424,16 @@ fn build_jump_hop_action_plan(
|
||||
JumpHopAssetRefresh::Preserve,
|
||||
now_micros,
|
||||
)?),
|
||||
JumpHopActionType::RegenerateCharacter => JumpHopActionProcedure::Compile(
|
||||
build_compile_input(
|
||||
JumpHopActionType::RegenerateCharacter => {
|
||||
JumpHopActionProcedure::Compile(build_compile_input(
|
||||
current,
|
||||
owner_user_id,
|
||||
&profile_id,
|
||||
&mut draft,
|
||||
JumpHopAssetRefresh::Character,
|
||||
now_micros,
|
||||
)?,
|
||||
),
|
||||
)?)
|
||||
}
|
||||
JumpHopActionType::RegenerateTiles => JumpHopActionProcedure::Compile(build_compile_input(
|
||||
current,
|
||||
owner_user_id,
|
||||
@@ -472,7 +466,11 @@ fn merge_action_into_draft(
|
||||
scope,
|
||||
JumpHopDraftMergeScope::CompileDraft | JumpHopDraftMergeScope::UpdateWorkMeta
|
||||
) {
|
||||
if let Some(value) = payload.work_title.as_ref().filter(|value| !value.trim().is_empty()) {
|
||||
if let Some(value) = payload
|
||||
.work_title
|
||||
.as_ref()
|
||||
.filter(|value| !value.trim().is_empty())
|
||||
{
|
||||
draft.work_title = value.trim().to_string();
|
||||
}
|
||||
if let Some(value) = payload.work_description.as_ref() {
|
||||
@@ -523,7 +521,9 @@ fn merge_action_into_draft(
|
||||
draft.tile_prompt = value.trim().to_string();
|
||||
}
|
||||
if draft.work_title.trim().is_empty() {
|
||||
return Err(SpacetimeClientError::validation_failed("jump-hop work_title 不能为空"));
|
||||
return Err(SpacetimeClientError::validation_failed(
|
||||
"jump-hop work_title 不能为空",
|
||||
));
|
||||
}
|
||||
Ok(draft)
|
||||
}
|
||||
@@ -762,7 +762,9 @@ fn ensure_tile_assets(
|
||||
.map(|(index, tile_type)| JumpHopTileAsset {
|
||||
tile_type,
|
||||
image_src: format!("/generated-jump-hop-assets/{profile_id}/tiles/{index}{suffix}.png"),
|
||||
image_object_key: format!("generated-jump-hop-assets/{profile_id}/tiles/{index}{suffix}.png"),
|
||||
image_object_key: format!(
|
||||
"generated-jump-hop-assets/{profile_id}/tiles/{index}{suffix}.png"
|
||||
),
|
||||
asset_object_id: format!("{profile_id}-tile-{index}{suffix}-object"),
|
||||
source_atlas_cell: format!("cell-{index}{suffix}"),
|
||||
visual_width: 256,
|
||||
@@ -788,7 +790,9 @@ fn resolve_cover_composite(
|
||||
{
|
||||
return Some(value.to_string());
|
||||
}
|
||||
let suffix = asset_revision_suffix((!matches!(refresh, JumpHopAssetRefresh::Preserve)).then_some(now_micros));
|
||||
let suffix = asset_revision_suffix(
|
||||
(!matches!(refresh, JumpHopAssetRefresh::Preserve)).then_some(now_micros),
|
||||
);
|
||||
Some(format!(
|
||||
"/generated-jump-hop-assets/{profile_id}/cover-composite{suffix}.png"
|
||||
))
|
||||
@@ -850,9 +854,27 @@ mod tests {
|
||||
assert_eq!(input.session_id, SESSION_ID);
|
||||
assert_eq!(input.owner_user_id, OWNER_USER_ID);
|
||||
assert_eq!(input.generation_status.as_deref(), Some("ready"));
|
||||
assert!(input.character_asset_json.as_deref().unwrap_or("").contains("-character"));
|
||||
assert!(input.tile_atlas_asset_json.as_deref().unwrap_or("").contains("-tile-atlas"));
|
||||
assert!(input.tile_assets_json.as_deref().unwrap_or("").contains("tile-0-object"));
|
||||
assert!(
|
||||
input
|
||||
.character_asset_json
|
||||
.as_deref()
|
||||
.unwrap_or("")
|
||||
.contains("-character")
|
||||
);
|
||||
assert!(
|
||||
input
|
||||
.tile_atlas_asset_json
|
||||
.as_deref()
|
||||
.unwrap_or("")
|
||||
.contains("-tile-atlas")
|
||||
);
|
||||
assert!(
|
||||
input
|
||||
.tile_assets_json
|
||||
.as_deref()
|
||||
.unwrap_or("")
|
||||
.contains("tile-0-object")
|
||||
);
|
||||
assert_eq!(draft.generation_status, JumpHopGenerationStatus::Ready);
|
||||
}
|
||||
|
||||
@@ -869,10 +891,34 @@ mod tests {
|
||||
let JumpHopActionProcedure::Compile(input) = plan else {
|
||||
panic!("regenerate-character should call compile_jump_hop_draft");
|
||||
};
|
||||
assert!(!input.character_asset_json.as_deref().unwrap_or("").contains("old-character"));
|
||||
assert!(input.character_asset_json.as_deref().unwrap_or("").contains(&NOW_MICROS.to_string()));
|
||||
assert!(input.tile_atlas_asset_json.as_deref().unwrap_or("").contains("old-tile-atlas"));
|
||||
assert!(input.tile_assets_json.as_deref().unwrap_or("").contains("old-normal-tile"));
|
||||
assert!(
|
||||
!input
|
||||
.character_asset_json
|
||||
.as_deref()
|
||||
.unwrap_or("")
|
||||
.contains("old-character")
|
||||
);
|
||||
assert!(
|
||||
input
|
||||
.character_asset_json
|
||||
.as_deref()
|
||||
.unwrap_or("")
|
||||
.contains(&NOW_MICROS.to_string())
|
||||
);
|
||||
assert!(
|
||||
input
|
||||
.tile_atlas_asset_json
|
||||
.as_deref()
|
||||
.unwrap_or("")
|
||||
.contains("old-tile-atlas")
|
||||
);
|
||||
assert!(
|
||||
input
|
||||
.tile_assets_json
|
||||
.as_deref()
|
||||
.unwrap_or("")
|
||||
.contains("old-normal-tile")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -888,11 +934,41 @@ mod tests {
|
||||
let JumpHopActionProcedure::Compile(input) = plan else {
|
||||
panic!("regenerate-tiles should call compile_jump_hop_draft");
|
||||
};
|
||||
assert!(input.character_asset_json.as_deref().unwrap_or("").contains("old-character"));
|
||||
assert!(!input.tile_atlas_asset_json.as_deref().unwrap_or("").contains("old-tile-atlas"));
|
||||
assert!(!input.tile_assets_json.as_deref().unwrap_or("").contains("old-normal-tile"));
|
||||
assert!(input.tile_atlas_asset_json.as_deref().unwrap_or("").contains(&NOW_MICROS.to_string()));
|
||||
assert!(input.tile_assets_json.as_deref().unwrap_or("").contains(&NOW_MICROS.to_string()));
|
||||
assert!(
|
||||
input
|
||||
.character_asset_json
|
||||
.as_deref()
|
||||
.unwrap_or("")
|
||||
.contains("old-character")
|
||||
);
|
||||
assert!(
|
||||
!input
|
||||
.tile_atlas_asset_json
|
||||
.as_deref()
|
||||
.unwrap_or("")
|
||||
.contains("old-tile-atlas")
|
||||
);
|
||||
assert!(
|
||||
!input
|
||||
.tile_assets_json
|
||||
.as_deref()
|
||||
.unwrap_or("")
|
||||
.contains("old-normal-tile")
|
||||
);
|
||||
assert!(
|
||||
input
|
||||
.tile_atlas_asset_json
|
||||
.as_deref()
|
||||
.unwrap_or("")
|
||||
.contains(&NOW_MICROS.to_string())
|
||||
);
|
||||
assert!(
|
||||
input
|
||||
.tile_assets_json
|
||||
.as_deref()
|
||||
.unwrap_or("")
|
||||
.contains(&NOW_MICROS.to_string())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -934,8 +1010,20 @@ mod tests {
|
||||
};
|
||||
assert_eq!(input.difficulty.as_deref(), Some("challenge"));
|
||||
assert!(input.style_preset.is_none());
|
||||
assert_eq!(draft.character_asset.as_ref().map(|asset| asset.asset_id.as_str()), Some("old-character"));
|
||||
assert_eq!(draft.tile_assets.first().map(|asset| asset.asset_object_id.as_str()), Some("old-normal-tile-object"));
|
||||
assert_eq!(
|
||||
draft
|
||||
.character_asset
|
||||
.as_ref()
|
||||
.map(|asset| asset.asset_id.as_str()),
|
||||
Some("old-character")
|
||||
);
|
||||
assert_eq!(
|
||||
draft
|
||||
.tile_assets
|
||||
.first()
|
||||
.map(|asset| asset.asset_object_id.as_str()),
|
||||
Some("old-normal-tile-object")
|
||||
);
|
||||
}
|
||||
|
||||
fn action(action_type: JumpHopActionType) -> JumpHopActionRequest {
|
||||
|
||||
@@ -30,16 +30,8 @@ pub use mapper::{
|
||||
CustomWorldPublishGateRecord, CustomWorldPublishWorldRecord,
|
||||
CustomWorldPublishWorldRecordInput, CustomWorldPublishedProfileCompileRecord,
|
||||
CustomWorldResultPreviewBlockerRecord, CustomWorldSupportedActionRecord,
|
||||
CustomWorldWorkSummaryRecord, Match3DAgentMessageFinalizeRecordInput,
|
||||
Match3DAgentMessageRecord, Match3DAgentMessageSubmitRecordInput,
|
||||
Match3DAgentSessionCreateRecordInput, Match3DAgentSessionRecord, Match3DAnchorItemRecord,
|
||||
Match3DAnchorPackRecord, Match3DClickConfirmationRecord, Match3DCompileDraftRecordInput,
|
||||
Match3DCreatorConfigRecord, Match3DItemSnapshotRecord, Match3DResultDraftRecord,
|
||||
Match3DRunClickRecordInput, Match3DRunRecord, Match3DRunRestartRecordInput,
|
||||
Match3DRunStartRecordInput, Match3DRunStopRecordInput, Match3DRunTimeUpRecordInput,
|
||||
Match3DTraySlotRecord, Match3DWorkProfileRecord, Match3DWorkUpdateRecordInput,
|
||||
JumpHopActionRequest, JumpHopActionResponse, JumpHopActionType, JumpHopCharacterAsset,
|
||||
JumpHopDifficulty, JumpHopDraftResponse, JumpHopGalleryCardResponse,
|
||||
CustomWorldWorkSummaryRecord, JumpHopActionRequest, JumpHopActionResponse, JumpHopActionType,
|
||||
JumpHopCharacterAsset, JumpHopDifficulty, JumpHopDraftResponse, JumpHopGalleryCardResponse,
|
||||
JumpHopGalleryDetailResponse, JumpHopGalleryResponse, JumpHopGenerationStatus,
|
||||
JumpHopJumpRequest, JumpHopJumpResponse, JumpHopJumpResult, JumpHopLastJump, JumpHopPath,
|
||||
JumpHopPlatform, JumpHopRestartRunRequest, JumpHopRunResponse, JumpHopRunStatus,
|
||||
@@ -47,7 +39,14 @@ pub use mapper::{
|
||||
JumpHopSessionSnapshotResponse, JumpHopStartRunRequest, JumpHopStylePreset, JumpHopTileAsset,
|
||||
JumpHopTileType, JumpHopWorkDetailResponse, JumpHopWorkMutationResponse,
|
||||
JumpHopWorkProfileResponse, JumpHopWorkSummaryResponse, JumpHopWorksResponse,
|
||||
JumpHopWorkspaceCreateRequest,
|
||||
JumpHopWorkspaceCreateRequest, Match3DAgentMessageFinalizeRecordInput,
|
||||
Match3DAgentMessageRecord, Match3DAgentMessageSubmitRecordInput,
|
||||
Match3DAgentSessionCreateRecordInput, Match3DAgentSessionRecord, Match3DAnchorItemRecord,
|
||||
Match3DAnchorPackRecord, Match3DClickConfirmationRecord, Match3DCompileDraftRecordInput,
|
||||
Match3DCreatorConfigRecord, Match3DItemSnapshotRecord, Match3DResultDraftRecord,
|
||||
Match3DRunClickRecordInput, Match3DRunRecord, Match3DRunRestartRecordInput,
|
||||
Match3DRunStartRecordInput, Match3DRunStopRecordInput, Match3DRunTimeUpRecordInput,
|
||||
Match3DTraySlotRecord, Match3DWorkProfileRecord, Match3DWorkUpdateRecordInput,
|
||||
NpcBattleInteractionRecord, NpcInteractionRecord, NpcStateRecord,
|
||||
PuzzleAgentMessageFinalizeRecordInput, PuzzleAgentMessageRecord,
|
||||
PuzzleAgentMessageSubmitRecordInput, PuzzleAgentSessionCreateRecordInput,
|
||||
@@ -80,7 +79,15 @@ pub use mapper::{
|
||||
VisualNovelHistoryEntryRecordInput, VisualNovelRunRecord, VisualNovelRunSnapshotRecordInput,
|
||||
VisualNovelRunStartRecordInput, VisualNovelRuntimeEventRecord,
|
||||
VisualNovelRuntimeEventRecordInput, VisualNovelWorkCompileRecordInput,
|
||||
VisualNovelWorkProfileRecord, VisualNovelWorkUpdateRecordInput,
|
||||
VisualNovelWorkProfileRecord, VisualNovelWorkUpdateRecordInput, WoodenFishActionRequest,
|
||||
WoodenFishActionResponse, WoodenFishActionType, WoodenFishAudioAsset,
|
||||
WoodenFishCheckpointRunRequest, WoodenFishDraftResponse, WoodenFishFinishRunRequest,
|
||||
WoodenFishGalleryCardResponse, WoodenFishGalleryDetailResponse, WoodenFishGalleryResponse,
|
||||
WoodenFishGenerationStatus, WoodenFishImageAsset, WoodenFishRunResponse, WoodenFishRunStatus,
|
||||
WoodenFishRuntimeRunSnapshotResponse, WoodenFishSessionResponse,
|
||||
WoodenFishSessionSnapshotResponse, WoodenFishStartRunRequest, WoodenFishWordCounter,
|
||||
WoodenFishWorkDetailResponse, WoodenFishWorkMutationResponse, WoodenFishWorkProfileResponse,
|
||||
WoodenFishWorkSummaryResponse, WoodenFishWorkspaceCreateRequest,
|
||||
};
|
||||
|
||||
pub mod ai;
|
||||
@@ -105,6 +112,7 @@ pub mod square_hole;
|
||||
pub mod story;
|
||||
pub mod story_runtime;
|
||||
pub mod visual_novel;
|
||||
pub mod wooden_fish;
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
@@ -563,6 +571,7 @@ impl SpacetimeClient {
|
||||
for query in [
|
||||
"SELECT * FROM puzzle_gallery_card_view",
|
||||
"SELECT * FROM jump_hop_gallery_card_view",
|
||||
"SELECT * FROM wooden_fish_gallery_card_view",
|
||||
"SELECT * FROM custom_world_gallery_entry",
|
||||
"SELECT * FROM match_3_d_gallery_view",
|
||||
"SELECT * FROM square_hole_gallery_view",
|
||||
@@ -578,6 +587,7 @@ impl SpacetimeClient {
|
||||
for query in [
|
||||
"SELECT * FROM public_work_play_daily_stat WHERE source_type = 'puzzle'",
|
||||
"SELECT * FROM public_work_play_daily_stat WHERE source_type = 'jump-hop'",
|
||||
"SELECT * FROM public_work_play_daily_stat WHERE source_type = 'wooden-fish'",
|
||||
"SELECT * FROM public_work_play_daily_stat WHERE source_type = 'custom-world'",
|
||||
"SELECT * FROM public_work_play_daily_stat WHERE source_type = 'match3d'",
|
||||
"SELECT * FROM public_work_play_daily_stat WHERE source_type = 'square-hole'",
|
||||
|
||||
@@ -18,6 +18,7 @@ mod runtime_profile;
|
||||
mod square_hole;
|
||||
mod story;
|
||||
mod visual_novel;
|
||||
mod wooden_fish;
|
||||
|
||||
pub use self::ai::{
|
||||
AiResultReferenceRecord, AiTaskMutationRecord, AiTaskRecord, AiTaskStageRecord,
|
||||
@@ -36,18 +37,6 @@ pub use self::combat::{
|
||||
BarkBattleDraftConfigRecord, BarkBattleRunRecord, BarkBattleRuntimeConfigRecord,
|
||||
ResolveCombatActionRecord,
|
||||
};
|
||||
pub use self::jump_hop::{
|
||||
JumpHopActionRequest, JumpHopActionResponse, JumpHopActionType, JumpHopCharacterAsset,
|
||||
JumpHopDifficulty, JumpHopDraftResponse, JumpHopGalleryCardResponse,
|
||||
JumpHopGalleryDetailResponse, JumpHopGalleryResponse, JumpHopGenerationStatus,
|
||||
JumpHopJumpRequest, JumpHopJumpResponse, JumpHopJumpResult, JumpHopLastJump, JumpHopPath,
|
||||
JumpHopPlatform, JumpHopRestartRunRequest, JumpHopRunResponse, JumpHopRunStatus,
|
||||
JumpHopRuntimeRunSnapshotResponse, JumpHopScoring, JumpHopSessionResponse,
|
||||
JumpHopSessionSnapshotResponse, JumpHopStartRunRequest, JumpHopStylePreset, JumpHopTileAsset,
|
||||
JumpHopTileType, JumpHopWorkDetailResponse, JumpHopWorkMutationResponse,
|
||||
JumpHopWorkProfileResponse, JumpHopWorkSummaryResponse, JumpHopWorksResponse,
|
||||
JumpHopWorkspaceCreateRequest,
|
||||
};
|
||||
pub use self::common::{
|
||||
BigFishAgentMessageRecord, BigFishAnchorItemRecord, BigFishAnchorPackRecord,
|
||||
BigFishBackgroundBlueprintRecord, BigFishDraftCompileRecordInput,
|
||||
@@ -77,6 +66,18 @@ pub use self::common::{
|
||||
VisualNovelRunSnapshotRecordInput, VisualNovelRunStartRecordInput,
|
||||
VisualNovelWorkCompileRecordInput,
|
||||
};
|
||||
pub use self::jump_hop::{
|
||||
JumpHopActionRequest, JumpHopActionResponse, JumpHopActionType, JumpHopCharacterAsset,
|
||||
JumpHopDifficulty, JumpHopDraftResponse, JumpHopGalleryCardResponse,
|
||||
JumpHopGalleryDetailResponse, JumpHopGalleryResponse, JumpHopGenerationStatus,
|
||||
JumpHopJumpRequest, JumpHopJumpResponse, JumpHopJumpResult, JumpHopLastJump, JumpHopPath,
|
||||
JumpHopPlatform, JumpHopRestartRunRequest, JumpHopRunResponse, JumpHopRunStatus,
|
||||
JumpHopRuntimeRunSnapshotResponse, JumpHopScoring, JumpHopSessionResponse,
|
||||
JumpHopSessionSnapshotResponse, JumpHopStartRunRequest, JumpHopStylePreset, JumpHopTileAsset,
|
||||
JumpHopTileType, JumpHopWorkDetailResponse, JumpHopWorkMutationResponse,
|
||||
JumpHopWorkProfileResponse, JumpHopWorkSummaryResponse, JumpHopWorksResponse,
|
||||
JumpHopWorkspaceCreateRequest,
|
||||
};
|
||||
pub use self::match3d::{
|
||||
Match3DAgentMessageFinalizeRecordInput, Match3DAgentMessageRecord,
|
||||
Match3DAgentMessageSubmitRecordInput, Match3DAgentSessionCreateRecordInput,
|
||||
@@ -118,6 +119,16 @@ pub use self::runtime_profile::{
|
||||
SquareHoleDropConfirmationRecord, SquareHoleDropFeedbackRecord, SquareHoleRunRecord,
|
||||
};
|
||||
pub use self::story::{VisualNovelRuntimeEventRecord, VisualNovelRuntimeEventRecordInput};
|
||||
pub use self::wooden_fish::{
|
||||
WoodenFishActionRequest, WoodenFishActionResponse, WoodenFishActionType, WoodenFishAudioAsset,
|
||||
WoodenFishCheckpointRunRequest, WoodenFishDraftResponse, WoodenFishFinishRunRequest,
|
||||
WoodenFishGalleryCardResponse, WoodenFishGalleryDetailResponse, WoodenFishGalleryResponse,
|
||||
WoodenFishGenerationStatus, WoodenFishImageAsset, WoodenFishRunResponse, WoodenFishRunStatus,
|
||||
WoodenFishRuntimeRunSnapshotResponse, WoodenFishSessionResponse,
|
||||
WoodenFishSessionSnapshotResponse, WoodenFishStartRunRequest, WoodenFishWordCounter,
|
||||
WoodenFishWorkDetailResponse, WoodenFishWorkMutationResponse, WoodenFishWorkProfileResponse,
|
||||
WoodenFishWorkSummaryResponse, WoodenFishWorkspaceCreateRequest,
|
||||
};
|
||||
|
||||
pub(crate) use self::ai::map_ai_task_procedure_result;
|
||||
pub(crate) use self::assets::{map_entity_binding_procedure_result, map_procedure_result};
|
||||
@@ -220,3 +231,8 @@ pub(crate) use self::visual_novel::{
|
||||
map_visual_novel_runtime_event_procedure_result, map_visual_novel_work_procedure_result,
|
||||
map_visual_novel_works_procedure_result,
|
||||
};
|
||||
pub(crate) use self::wooden_fish::{
|
||||
map_wooden_fish_agent_session_procedure_result, map_wooden_fish_gallery_card_view_row,
|
||||
map_wooden_fish_run_procedure_result, map_wooden_fish_work_procedure_result,
|
||||
map_wooden_fish_works_procedure_result,
|
||||
};
|
||||
|
||||
@@ -161,7 +161,11 @@ fn map_jump_hop_work_snapshot(
|
||||
path: map_jump_hop_path(snapshot.path),
|
||||
character_asset,
|
||||
tile_atlas_asset,
|
||||
tile_assets: snapshot.tile_assets.into_iter().map(map_tile_asset).collect(),
|
||||
tile_assets: snapshot
|
||||
.tile_assets
|
||||
.into_iter()
|
||||
.map(map_tile_asset)
|
||||
.collect(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -180,7 +184,11 @@ fn map_jump_hop_draft_snapshot(snapshot: JumpHopDraftSnapshot) -> JumpHopDraftRe
|
||||
end_mood_prompt: snapshot.end_mood_prompt,
|
||||
character_asset: snapshot.character_asset.map(map_character_asset),
|
||||
tile_atlas_asset: snapshot.tile_atlas_asset.map(map_character_asset),
|
||||
tile_assets: snapshot.tile_assets.into_iter().map(map_tile_asset).collect(),
|
||||
tile_assets: snapshot
|
||||
.tile_assets
|
||||
.into_iter()
|
||||
.map(map_tile_asset)
|
||||
.collect(),
|
||||
path: snapshot.path.map(map_jump_hop_path),
|
||||
cover_composite: snapshot.cover_composite,
|
||||
generation_status: parse_generation_status(&snapshot.generation_status),
|
||||
@@ -268,7 +276,9 @@ fn map_jump_hop_run_snapshot(snapshot: JumpHopRunSnapshot) -> JumpHopRuntimeRunS
|
||||
crate::module_bindings::JumpHopJumpResultKind::Miss => JumpHopJumpResult::Miss,
|
||||
crate::module_bindings::JumpHopJumpResultKind::Hit => JumpHopJumpResult::Hit,
|
||||
crate::module_bindings::JumpHopJumpResultKind::Finish => JumpHopJumpResult::Finish,
|
||||
crate::module_bindings::JumpHopJumpResultKind::Perfect => JumpHopJumpResult::Perfect,
|
||||
crate::module_bindings::JumpHopJumpResultKind::Perfect => {
|
||||
JumpHopJumpResult::Perfect
|
||||
}
|
||||
},
|
||||
}),
|
||||
started_at_ms: snapshot.started_at_ms,
|
||||
|
||||
237
server-rs/crates/spacetime-client/src/mapper/wooden_fish.rs
Normal file
237
server-rs/crates/spacetime-client/src/mapper/wooden_fish.rs
Normal file
@@ -0,0 +1,237 @@
|
||||
use super::*;
|
||||
pub use shared_contracts::wooden_fish::{
|
||||
WoodenFishActionRequest, WoodenFishActionResponse, WoodenFishActionType, WoodenFishAudioAsset,
|
||||
WoodenFishCheckpointRunRequest, WoodenFishDraftResponse, WoodenFishFinishRunRequest,
|
||||
WoodenFishGalleryCardResponse, WoodenFishGalleryDetailResponse, WoodenFishGalleryResponse,
|
||||
WoodenFishGenerationStatus, WoodenFishImageAsset, WoodenFishRunResponse, WoodenFishRunStatus,
|
||||
WoodenFishRuntimeRunSnapshotResponse, WoodenFishSessionResponse,
|
||||
WoodenFishSessionSnapshotResponse, WoodenFishStartRunRequest, WoodenFishWordCounter,
|
||||
WoodenFishWorkDetailResponse, WoodenFishWorkMutationResponse, WoodenFishWorkProfileResponse,
|
||||
WoodenFishWorkSummaryResponse, WoodenFishWorkspaceCreateRequest,
|
||||
};
|
||||
|
||||
pub(crate) fn map_wooden_fish_agent_session_procedure_result(
|
||||
result: WoodenFishAgentSessionProcedureResult,
|
||||
) -> Result<WoodenFishSessionSnapshotResponse, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
||||
}
|
||||
let session = result
|
||||
.session
|
||||
.ok_or_else(|| SpacetimeClientError::missing_snapshot("wooden fish agent session 快照"))?;
|
||||
Ok(map_wooden_fish_session_snapshot(session))
|
||||
}
|
||||
|
||||
pub(crate) fn map_wooden_fish_work_procedure_result(
|
||||
result: WoodenFishWorkProcedureResult,
|
||||
) -> Result<WoodenFishWorkProfileResponse, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
||||
}
|
||||
let work = result
|
||||
.work
|
||||
.ok_or_else(|| SpacetimeClientError::missing_snapshot("wooden fish work 快照"))?;
|
||||
map_wooden_fish_work_snapshot(work)
|
||||
}
|
||||
|
||||
pub(crate) fn map_wooden_fish_works_procedure_result(
|
||||
result: WoodenFishWorksProcedureResult,
|
||||
) -> Result<Vec<WoodenFishWorkProfileResponse>, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
||||
}
|
||||
result
|
||||
.items
|
||||
.into_iter()
|
||||
.map(map_wooden_fish_work_snapshot)
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub(crate) fn map_wooden_fish_run_procedure_result(
|
||||
result: WoodenFishRunProcedureResult,
|
||||
) -> Result<WoodenFishRuntimeRunSnapshotResponse, SpacetimeClientError> {
|
||||
if !result.ok {
|
||||
return Err(SpacetimeClientError::procedure_failed(result.error_message));
|
||||
}
|
||||
let run = result
|
||||
.run
|
||||
.ok_or_else(|| SpacetimeClientError::missing_snapshot("wooden fish run 快照"))?;
|
||||
Ok(map_wooden_fish_run_snapshot(run))
|
||||
}
|
||||
|
||||
pub(crate) fn map_wooden_fish_gallery_card_view_row(
|
||||
row: WoodenFishGalleryCardViewRow,
|
||||
) -> WoodenFishGalleryCardResponse {
|
||||
WoodenFishGalleryCardResponse {
|
||||
public_work_code: row.public_work_code,
|
||||
work_id: row.work_id,
|
||||
profile_id: row.profile_id,
|
||||
owner_user_id: row.owner_user_id,
|
||||
author_display_name: row.author_display_name,
|
||||
work_title: row.work_title,
|
||||
work_description: row.work_description,
|
||||
cover_image_src: empty_string_to_none(row.cover_image_src),
|
||||
theme_tags: row.theme_tags,
|
||||
publication_status: normalize_publication_status(&row.publication_status).to_string(),
|
||||
play_count: row.play_count,
|
||||
updated_at: format_timestamp_micros(row.updated_at_micros),
|
||||
published_at: row.published_at_micros.map(format_timestamp_micros),
|
||||
generation_status: parse_generation_status(&row.generation_status),
|
||||
}
|
||||
}
|
||||
|
||||
fn map_wooden_fish_session_snapshot(
|
||||
snapshot: WoodenFishAgentSessionSnapshot,
|
||||
) -> WoodenFishSessionSnapshotResponse {
|
||||
WoodenFishSessionSnapshotResponse {
|
||||
session_id: snapshot.session_id,
|
||||
owner_user_id: snapshot.owner_user_id,
|
||||
status: snapshot
|
||||
.draft
|
||||
.as_ref()
|
||||
.map(|draft| parse_generation_status(&draft.generation_status))
|
||||
.unwrap_or(WoodenFishGenerationStatus::Draft),
|
||||
draft: snapshot.draft.map(map_wooden_fish_draft_snapshot),
|
||||
created_at: format_timestamp_micros(snapshot.created_at_micros),
|
||||
updated_at: format_timestamp_micros(snapshot.updated_at_micros),
|
||||
}
|
||||
}
|
||||
|
||||
fn map_wooden_fish_work_snapshot(
|
||||
snapshot: WoodenFishWorkSnapshot,
|
||||
) -> Result<WoodenFishWorkProfileResponse, SpacetimeClientError> {
|
||||
let draft = WoodenFishDraftResponse {
|
||||
template_id: "wooden-fish".to_string(),
|
||||
template_name: "敲木鱼".to_string(),
|
||||
profile_id: Some(snapshot.profile_id.clone()),
|
||||
work_title: snapshot.work_title.clone(),
|
||||
work_description: snapshot.work_description.clone(),
|
||||
theme_tags: snapshot.theme_tags.clone(),
|
||||
hit_object_prompt: snapshot.hit_object_prompt.clone(),
|
||||
hit_object_reference_image_src: snapshot.hit_object_reference_image_src.clone(),
|
||||
hit_sound_prompt: snapshot.hit_sound_prompt.clone(),
|
||||
floating_words: snapshot.floating_words.clone(),
|
||||
hit_object_asset: snapshot.hit_object_asset.clone().map(map_image_asset),
|
||||
hit_sound_asset: snapshot.hit_sound_asset.clone().map(map_audio_asset),
|
||||
cover_image_src: empty_string_to_none(snapshot.cover_image_src.clone()),
|
||||
generation_status: parse_generation_status(&snapshot.generation_status),
|
||||
};
|
||||
let hit_object_asset = draft
|
||||
.hit_object_asset
|
||||
.clone()
|
||||
.ok_or_else(|| SpacetimeClientError::missing_snapshot("wooden fish hit object asset"))?;
|
||||
let hit_sound_asset = draft
|
||||
.hit_sound_asset
|
||||
.clone()
|
||||
.ok_or_else(|| SpacetimeClientError::missing_snapshot("wooden fish hit sound asset"))?;
|
||||
Ok(WoodenFishWorkProfileResponse {
|
||||
summary: WoodenFishWorkSummaryResponse {
|
||||
runtime_kind: "wooden-fish".to_string(),
|
||||
work_id: snapshot.work_id,
|
||||
profile_id: snapshot.profile_id,
|
||||
owner_user_id: snapshot.owner_user_id,
|
||||
source_session_id: empty_string_to_none(snapshot.source_session_id),
|
||||
work_title: snapshot.work_title,
|
||||
work_description: snapshot.work_description,
|
||||
theme_tags: snapshot.theme_tags,
|
||||
cover_image_src: empty_string_to_none(snapshot.cover_image_src),
|
||||
publication_status: normalize_publication_status(&snapshot.publication_status)
|
||||
.to_string(),
|
||||
play_count: snapshot.play_count,
|
||||
updated_at: format_timestamp_micros(snapshot.updated_at_micros),
|
||||
published_at: snapshot.published_at_micros.map(format_timestamp_micros),
|
||||
publish_ready: snapshot.publish_ready,
|
||||
generation_status: parse_generation_status(&snapshot.generation_status),
|
||||
},
|
||||
draft,
|
||||
hit_object_asset,
|
||||
hit_sound_asset,
|
||||
floating_words: snapshot.floating_words,
|
||||
})
|
||||
}
|
||||
|
||||
fn map_wooden_fish_draft_snapshot(snapshot: WoodenFishDraftSnapshot) -> WoodenFishDraftResponse {
|
||||
WoodenFishDraftResponse {
|
||||
template_id: snapshot.template_id,
|
||||
template_name: snapshot.template_name,
|
||||
profile_id: snapshot.profile_id,
|
||||
work_title: snapshot.work_title,
|
||||
work_description: snapshot.work_description,
|
||||
theme_tags: snapshot.theme_tags,
|
||||
hit_object_prompt: snapshot.hit_object_prompt,
|
||||
hit_object_reference_image_src: snapshot.hit_object_reference_image_src,
|
||||
hit_sound_prompt: snapshot.hit_sound_prompt,
|
||||
floating_words: snapshot.floating_words,
|
||||
hit_object_asset: snapshot.hit_object_asset.map(map_image_asset),
|
||||
hit_sound_asset: snapshot.hit_sound_asset.map(map_audio_asset),
|
||||
cover_image_src: snapshot.cover_image_src,
|
||||
generation_status: parse_generation_status(&snapshot.generation_status),
|
||||
}
|
||||
}
|
||||
|
||||
fn map_image_asset(snapshot: WoodenFishImageAssetSnapshot) -> WoodenFishImageAsset {
|
||||
WoodenFishImageAsset {
|
||||
asset_id: snapshot.asset_id,
|
||||
image_src: snapshot.image_src,
|
||||
image_object_key: snapshot.image_object_key,
|
||||
asset_object_id: snapshot.asset_object_id,
|
||||
generation_provider: snapshot.generation_provider,
|
||||
prompt: snapshot.prompt,
|
||||
width: snapshot.width,
|
||||
height: snapshot.height,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_audio_asset(snapshot: WoodenFishAudioAssetSnapshot) -> WoodenFishAudioAsset {
|
||||
WoodenFishAudioAsset {
|
||||
asset_id: snapshot.asset_id,
|
||||
audio_src: snapshot.audio_src,
|
||||
audio_object_key: snapshot.audio_object_key,
|
||||
asset_object_id: snapshot.asset_object_id,
|
||||
source: snapshot.source,
|
||||
prompt: snapshot.prompt,
|
||||
duration_ms: snapshot.duration_ms,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_wooden_fish_run_snapshot(
|
||||
snapshot: crate::module_bindings::WoodenFishRunSnapshot,
|
||||
) -> WoodenFishRuntimeRunSnapshotResponse {
|
||||
WoodenFishRuntimeRunSnapshotResponse {
|
||||
run_id: snapshot.run_id,
|
||||
profile_id: snapshot.profile_id,
|
||||
owner_user_id: snapshot.owner_user_id,
|
||||
status: match snapshot.status {
|
||||
crate::module_bindings::WoodenFishRunStatus::Playing => WoodenFishRunStatus::Playing,
|
||||
crate::module_bindings::WoodenFishRunStatus::Finished => WoodenFishRunStatus::Finished,
|
||||
},
|
||||
total_tap_count: snapshot.total_tap_count,
|
||||
word_counters: snapshot
|
||||
.word_counters
|
||||
.into_iter()
|
||||
.map(|counter| WoodenFishWordCounter {
|
||||
text: counter.text,
|
||||
count: counter.count,
|
||||
})
|
||||
.collect(),
|
||||
started_at_ms: snapshot.started_at_ms,
|
||||
updated_at_ms: snapshot.updated_at_ms,
|
||||
finished_at_ms: snapshot.finished_at_ms,
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_generation_status(value: &str) -> WoodenFishGenerationStatus {
|
||||
match value {
|
||||
"generating" => WoodenFishGenerationStatus::Generating,
|
||||
"ready" => WoodenFishGenerationStatus::Ready,
|
||||
"failed" => WoodenFishGenerationStatus::Failed,
|
||||
_ => WoodenFishGenerationStatus::Draft,
|
||||
}
|
||||
}
|
||||
|
||||
fn normalize_publication_status(value: &str) -> &str {
|
||||
match value {
|
||||
"Published" | "published" => "published",
|
||||
_ => "draft",
|
||||
}
|
||||
}
|
||||
@@ -191,6 +191,7 @@ pub mod chapter_progression_procedure_result_type;
|
||||
pub mod chapter_progression_snapshot_type;
|
||||
pub mod chapter_progression_table;
|
||||
pub mod chapter_progression_type;
|
||||
pub mod checkpoint_wooden_fish_run_procedure;
|
||||
pub mod claim_profile_task_reward_and_return_procedure;
|
||||
pub mod claim_puzzle_work_point_incentive_procedure;
|
||||
pub mod clear_database_migration_import_chunks_procedure;
|
||||
@@ -204,6 +205,7 @@ pub mod compile_match_3_d_draft_procedure;
|
||||
pub mod compile_puzzle_agent_draft_procedure;
|
||||
pub mod compile_square_hole_draft_procedure;
|
||||
pub mod compile_visual_novel_work_profile_procedure;
|
||||
pub mod compile_wooden_fish_draft_procedure;
|
||||
pub mod complete_ai_stage_and_return_procedure;
|
||||
pub mod complete_ai_task_and_return_procedure;
|
||||
pub mod confirm_asset_object_and_return_procedure;
|
||||
@@ -225,6 +227,7 @@ pub mod create_profile_recharge_order_and_return_procedure;
|
||||
pub mod create_puzzle_agent_session_procedure;
|
||||
pub mod create_square_hole_agent_session_procedure;
|
||||
pub mod create_visual_novel_agent_session_procedure;
|
||||
pub mod create_wooden_fish_agent_session_procedure;
|
||||
pub mod creation_entry_config_procedure_result_type;
|
||||
pub mod creation_entry_config_snapshot_type;
|
||||
pub mod creation_entry_config_table;
|
||||
@@ -336,6 +339,7 @@ pub mod finalize_visual_novel_agent_message_turn_procedure;
|
||||
pub mod finish_bark_battle_run_procedure;
|
||||
pub mod finish_match_3_d_time_up_procedure;
|
||||
pub mod finish_square_hole_time_up_procedure;
|
||||
pub mod finish_wooden_fish_run_procedure;
|
||||
pub mod generate_big_fish_asset_procedure;
|
||||
pub mod get_auth_store_snapshot_procedure;
|
||||
pub mod get_bark_battle_run_procedure;
|
||||
@@ -378,6 +382,9 @@ pub mod get_story_session_state_procedure;
|
||||
pub mod get_visual_novel_agent_session_procedure;
|
||||
pub mod get_visual_novel_run_procedure;
|
||||
pub mod get_visual_novel_work_detail_procedure;
|
||||
pub mod get_wooden_fish_agent_session_procedure;
|
||||
pub mod get_wooden_fish_run_procedure;
|
||||
pub mod get_wooden_fish_work_profile_procedure;
|
||||
pub mod grant_inventory_item_input_type;
|
||||
pub mod grant_new_user_registration_wallet_reward_procedure;
|
||||
pub mod grant_player_progression_experience_and_return_procedure;
|
||||
@@ -456,6 +463,7 @@ pub mod list_puzzle_works_procedure;
|
||||
pub mod list_square_hole_works_procedure;
|
||||
pub mod list_visual_novel_runtime_history_procedure;
|
||||
pub mod list_visual_novel_works_procedure;
|
||||
pub mod list_wooden_fish_works_procedure;
|
||||
pub mod mark_profile_recharge_order_paid_and_return_procedure;
|
||||
pub mod match_3_d_agent_message_finalize_input_type;
|
||||
pub mod match_3_d_agent_message_row_type;
|
||||
@@ -562,6 +570,7 @@ pub mod publish_match_3_d_work_procedure;
|
||||
pub mod publish_puzzle_work_procedure;
|
||||
pub mod publish_square_hole_work_procedure;
|
||||
pub mod publish_visual_novel_work_procedure;
|
||||
pub mod publish_wooden_fish_work_procedure;
|
||||
pub mod put_database_migration_import_chunk_procedure;
|
||||
pub mod puzzle_agent_message_finalize_input_type;
|
||||
pub mod puzzle_agent_message_kind_type;
|
||||
@@ -876,6 +885,7 @@ pub mod start_match_3_d_run_procedure;
|
||||
pub mod start_puzzle_run_procedure;
|
||||
pub mod start_square_hole_run_procedure;
|
||||
pub mod start_visual_novel_run_procedure;
|
||||
pub mod start_wooden_fish_run_procedure;
|
||||
pub mod stop_match_3_d_run_procedure;
|
||||
pub mod stop_square_hole_run_procedure;
|
||||
pub mod story_continue_input_type;
|
||||
@@ -922,6 +932,7 @@ pub mod update_puzzle_run_pause_procedure;
|
||||
pub mod update_puzzle_work_procedure;
|
||||
pub mod update_square_hole_work_procedure;
|
||||
pub mod update_visual_novel_work_procedure;
|
||||
pub mod update_wooden_fish_work_procedure;
|
||||
pub mod upsert_auth_store_snapshot_procedure;
|
||||
pub mod upsert_chapter_progression_and_return_procedure;
|
||||
pub mod upsert_chapter_progression_reducer;
|
||||
@@ -984,6 +995,42 @@ pub mod visual_novel_work_snapshot_type;
|
||||
pub mod visual_novel_work_update_input_type;
|
||||
pub mod visual_novel_works_list_input_type;
|
||||
pub mod visual_novel_works_procedure_result_type;
|
||||
pub mod wooden_fish_agent_session_create_input_type;
|
||||
pub mod wooden_fish_agent_session_get_input_type;
|
||||
pub mod wooden_fish_agent_session_procedure_result_type;
|
||||
pub mod wooden_fish_agent_session_row_type;
|
||||
pub mod wooden_fish_agent_session_snapshot_type;
|
||||
pub mod wooden_fish_agent_session_table;
|
||||
pub mod wooden_fish_audio_asset_snapshot_type;
|
||||
pub mod wooden_fish_creator_config_snapshot_type;
|
||||
pub mod wooden_fish_draft_compile_input_type;
|
||||
pub mod wooden_fish_draft_snapshot_type;
|
||||
pub mod wooden_fish_event_row_type;
|
||||
pub mod wooden_fish_event_table;
|
||||
pub mod wooden_fish_gallery_card_view_row_type;
|
||||
pub mod wooden_fish_gallery_card_view_table;
|
||||
pub mod wooden_fish_gallery_view_row_type;
|
||||
pub mod wooden_fish_gallery_view_table;
|
||||
pub mod wooden_fish_image_asset_snapshot_type;
|
||||
pub mod wooden_fish_run_checkpoint_input_type;
|
||||
pub mod wooden_fish_run_finish_input_type;
|
||||
pub mod wooden_fish_run_get_input_type;
|
||||
pub mod wooden_fish_run_procedure_result_type;
|
||||
pub mod wooden_fish_run_snapshot_type;
|
||||
pub mod wooden_fish_run_start_input_type;
|
||||
pub mod wooden_fish_run_status_type;
|
||||
pub mod wooden_fish_runtime_run_row_type;
|
||||
pub mod wooden_fish_runtime_run_table;
|
||||
pub mod wooden_fish_word_counter_type;
|
||||
pub mod wooden_fish_work_get_input_type;
|
||||
pub mod wooden_fish_work_procedure_result_type;
|
||||
pub mod wooden_fish_work_profile_row_type;
|
||||
pub mod wooden_fish_work_profile_table;
|
||||
pub mod wooden_fish_work_publish_input_type;
|
||||
pub mod wooden_fish_work_snapshot_type;
|
||||
pub mod wooden_fish_work_update_input_type;
|
||||
pub mod wooden_fish_works_list_input_type;
|
||||
pub mod wooden_fish_works_procedure_result_type;
|
||||
|
||||
pub use accept_quest_reducer::accept_quest;
|
||||
pub use acknowledge_quest_completion_reducer::acknowledge_quest_completion;
|
||||
@@ -1170,6 +1217,7 @@ pub use chapter_progression_procedure_result_type::ChapterProgressionProcedureRe
|
||||
pub use chapter_progression_snapshot_type::ChapterProgressionSnapshot;
|
||||
pub use chapter_progression_table::*;
|
||||
pub use chapter_progression_type::ChapterProgression;
|
||||
pub use checkpoint_wooden_fish_run_procedure::checkpoint_wooden_fish_run;
|
||||
pub use claim_profile_task_reward_and_return_procedure::claim_profile_task_reward_and_return;
|
||||
pub use claim_puzzle_work_point_incentive_procedure::claim_puzzle_work_point_incentive;
|
||||
pub use clear_database_migration_import_chunks_procedure::clear_database_migration_import_chunks;
|
||||
@@ -1183,6 +1231,7 @@ pub use compile_match_3_d_draft_procedure::compile_match_3_d_draft;
|
||||
pub use compile_puzzle_agent_draft_procedure::compile_puzzle_agent_draft;
|
||||
pub use compile_square_hole_draft_procedure::compile_square_hole_draft;
|
||||
pub use compile_visual_novel_work_profile_procedure::compile_visual_novel_work_profile;
|
||||
pub use compile_wooden_fish_draft_procedure::compile_wooden_fish_draft;
|
||||
pub use complete_ai_stage_and_return_procedure::complete_ai_stage_and_return;
|
||||
pub use complete_ai_task_and_return_procedure::complete_ai_task_and_return;
|
||||
pub use confirm_asset_object_and_return_procedure::confirm_asset_object_and_return;
|
||||
@@ -1204,6 +1253,7 @@ pub use create_profile_recharge_order_and_return_procedure::create_profile_recha
|
||||
pub use create_puzzle_agent_session_procedure::create_puzzle_agent_session;
|
||||
pub use create_square_hole_agent_session_procedure::create_square_hole_agent_session;
|
||||
pub use create_visual_novel_agent_session_procedure::create_visual_novel_agent_session;
|
||||
pub use create_wooden_fish_agent_session_procedure::create_wooden_fish_agent_session;
|
||||
pub use creation_entry_config_procedure_result_type::CreationEntryConfigProcedureResult;
|
||||
pub use creation_entry_config_snapshot_type::CreationEntryConfigSnapshot;
|
||||
pub use creation_entry_config_table::*;
|
||||
@@ -1315,6 +1365,7 @@ pub use finalize_visual_novel_agent_message_turn_procedure::finalize_visual_nove
|
||||
pub use finish_bark_battle_run_procedure::finish_bark_battle_run;
|
||||
pub use finish_match_3_d_time_up_procedure::finish_match_3_d_time_up;
|
||||
pub use finish_square_hole_time_up_procedure::finish_square_hole_time_up;
|
||||
pub use finish_wooden_fish_run_procedure::finish_wooden_fish_run;
|
||||
pub use generate_big_fish_asset_procedure::generate_big_fish_asset;
|
||||
pub use get_auth_store_snapshot_procedure::get_auth_store_snapshot;
|
||||
pub use get_bark_battle_run_procedure::get_bark_battle_run;
|
||||
@@ -1357,6 +1408,9 @@ pub use get_story_session_state_procedure::get_story_session_state;
|
||||
pub use get_visual_novel_agent_session_procedure::get_visual_novel_agent_session;
|
||||
pub use get_visual_novel_run_procedure::get_visual_novel_run;
|
||||
pub use get_visual_novel_work_detail_procedure::get_visual_novel_work_detail;
|
||||
pub use get_wooden_fish_agent_session_procedure::get_wooden_fish_agent_session;
|
||||
pub use get_wooden_fish_run_procedure::get_wooden_fish_run;
|
||||
pub use get_wooden_fish_work_profile_procedure::get_wooden_fish_work_profile;
|
||||
pub use grant_inventory_item_input_type::GrantInventoryItemInput;
|
||||
pub use grant_new_user_registration_wallet_reward_procedure::grant_new_user_registration_wallet_reward;
|
||||
pub use grant_player_progression_experience_and_return_procedure::grant_player_progression_experience_and_return;
|
||||
@@ -1435,6 +1489,7 @@ pub use list_puzzle_works_procedure::list_puzzle_works;
|
||||
pub use list_square_hole_works_procedure::list_square_hole_works;
|
||||
pub use list_visual_novel_runtime_history_procedure::list_visual_novel_runtime_history;
|
||||
pub use list_visual_novel_works_procedure::list_visual_novel_works;
|
||||
pub use list_wooden_fish_works_procedure::list_wooden_fish_works;
|
||||
pub use mark_profile_recharge_order_paid_and_return_procedure::mark_profile_recharge_order_paid_and_return;
|
||||
pub use match_3_d_agent_message_finalize_input_type::Match3DAgentMessageFinalizeInput;
|
||||
pub use match_3_d_agent_message_row_type::Match3DAgentMessageRow;
|
||||
@@ -1541,6 +1596,7 @@ pub use publish_match_3_d_work_procedure::publish_match_3_d_work;
|
||||
pub use publish_puzzle_work_procedure::publish_puzzle_work;
|
||||
pub use publish_square_hole_work_procedure::publish_square_hole_work;
|
||||
pub use publish_visual_novel_work_procedure::publish_visual_novel_work;
|
||||
pub use publish_wooden_fish_work_procedure::publish_wooden_fish_work;
|
||||
pub use put_database_migration_import_chunk_procedure::put_database_migration_import_chunk;
|
||||
pub use puzzle_agent_message_finalize_input_type::PuzzleAgentMessageFinalizeInput;
|
||||
pub use puzzle_agent_message_kind_type::PuzzleAgentMessageKind;
|
||||
@@ -1855,6 +1911,7 @@ pub use start_match_3_d_run_procedure::start_match_3_d_run;
|
||||
pub use start_puzzle_run_procedure::start_puzzle_run;
|
||||
pub use start_square_hole_run_procedure::start_square_hole_run;
|
||||
pub use start_visual_novel_run_procedure::start_visual_novel_run;
|
||||
pub use start_wooden_fish_run_procedure::start_wooden_fish_run;
|
||||
pub use stop_match_3_d_run_procedure::stop_match_3_d_run;
|
||||
pub use stop_square_hole_run_procedure::stop_square_hole_run;
|
||||
pub use story_continue_input_type::StoryContinueInput;
|
||||
@@ -1901,6 +1958,7 @@ pub use update_puzzle_run_pause_procedure::update_puzzle_run_pause;
|
||||
pub use update_puzzle_work_procedure::update_puzzle_work;
|
||||
pub use update_square_hole_work_procedure::update_square_hole_work;
|
||||
pub use update_visual_novel_work_procedure::update_visual_novel_work;
|
||||
pub use update_wooden_fish_work_procedure::update_wooden_fish_work;
|
||||
pub use upsert_auth_store_snapshot_procedure::upsert_auth_store_snapshot;
|
||||
pub use upsert_chapter_progression_and_return_procedure::upsert_chapter_progression_and_return;
|
||||
pub use upsert_chapter_progression_reducer::upsert_chapter_progression;
|
||||
@@ -1963,6 +2021,42 @@ pub use visual_novel_work_snapshot_type::VisualNovelWorkSnapshot;
|
||||
pub use visual_novel_work_update_input_type::VisualNovelWorkUpdateInput;
|
||||
pub use visual_novel_works_list_input_type::VisualNovelWorksListInput;
|
||||
pub use visual_novel_works_procedure_result_type::VisualNovelWorksProcedureResult;
|
||||
pub use wooden_fish_agent_session_create_input_type::WoodenFishAgentSessionCreateInput;
|
||||
pub use wooden_fish_agent_session_get_input_type::WoodenFishAgentSessionGetInput;
|
||||
pub use wooden_fish_agent_session_procedure_result_type::WoodenFishAgentSessionProcedureResult;
|
||||
pub use wooden_fish_agent_session_row_type::WoodenFishAgentSessionRow;
|
||||
pub use wooden_fish_agent_session_snapshot_type::WoodenFishAgentSessionSnapshot;
|
||||
pub use wooden_fish_agent_session_table::*;
|
||||
pub use wooden_fish_audio_asset_snapshot_type::WoodenFishAudioAssetSnapshot;
|
||||
pub use wooden_fish_creator_config_snapshot_type::WoodenFishCreatorConfigSnapshot;
|
||||
pub use wooden_fish_draft_compile_input_type::WoodenFishDraftCompileInput;
|
||||
pub use wooden_fish_draft_snapshot_type::WoodenFishDraftSnapshot;
|
||||
pub use wooden_fish_event_row_type::WoodenFishEventRow;
|
||||
pub use wooden_fish_event_table::*;
|
||||
pub use wooden_fish_gallery_card_view_row_type::WoodenFishGalleryCardViewRow;
|
||||
pub use wooden_fish_gallery_card_view_table::*;
|
||||
pub use wooden_fish_gallery_view_row_type::WoodenFishGalleryViewRow;
|
||||
pub use wooden_fish_gallery_view_table::*;
|
||||
pub use wooden_fish_image_asset_snapshot_type::WoodenFishImageAssetSnapshot;
|
||||
pub use wooden_fish_run_checkpoint_input_type::WoodenFishRunCheckpointInput;
|
||||
pub use wooden_fish_run_finish_input_type::WoodenFishRunFinishInput;
|
||||
pub use wooden_fish_run_get_input_type::WoodenFishRunGetInput;
|
||||
pub use wooden_fish_run_procedure_result_type::WoodenFishRunProcedureResult;
|
||||
pub use wooden_fish_run_snapshot_type::WoodenFishRunSnapshot;
|
||||
pub use wooden_fish_run_start_input_type::WoodenFishRunStartInput;
|
||||
pub use wooden_fish_run_status_type::WoodenFishRunStatus;
|
||||
pub use wooden_fish_runtime_run_row_type::WoodenFishRuntimeRunRow;
|
||||
pub use wooden_fish_runtime_run_table::*;
|
||||
pub use wooden_fish_word_counter_type::WoodenFishWordCounter;
|
||||
pub use wooden_fish_work_get_input_type::WoodenFishWorkGetInput;
|
||||
pub use wooden_fish_work_procedure_result_type::WoodenFishWorkProcedureResult;
|
||||
pub use wooden_fish_work_profile_row_type::WoodenFishWorkProfileRow;
|
||||
pub use wooden_fish_work_profile_table::*;
|
||||
pub use wooden_fish_work_publish_input_type::WoodenFishWorkPublishInput;
|
||||
pub use wooden_fish_work_snapshot_type::WoodenFishWorkSnapshot;
|
||||
pub use wooden_fish_work_update_input_type::WoodenFishWorkUpdateInput;
|
||||
pub use wooden_fish_works_list_input_type::WoodenFishWorksListInput;
|
||||
pub use wooden_fish_works_procedure_result_type::WoodenFishWorksProcedureResult;
|
||||
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
|
||||
@@ -2337,6 +2431,12 @@ pub struct DbUpdate {
|
||||
visual_novel_runtime_history_entry: __sdk::TableUpdate<VisualNovelRuntimeHistoryEntryRow>,
|
||||
visual_novel_runtime_run: __sdk::TableUpdate<VisualNovelRuntimeRunRow>,
|
||||
visual_novel_work_profile: __sdk::TableUpdate<VisualNovelWorkProfileRow>,
|
||||
wooden_fish_agent_session: __sdk::TableUpdate<WoodenFishAgentSessionRow>,
|
||||
wooden_fish_event: __sdk::TableUpdate<WoodenFishEventRow>,
|
||||
wooden_fish_gallery_card_view: __sdk::TableUpdate<WoodenFishGalleryCardViewRow>,
|
||||
wooden_fish_gallery_view: __sdk::TableUpdate<WoodenFishGalleryViewRow>,
|
||||
wooden_fish_runtime_run: __sdk::TableUpdate<WoodenFishRuntimeRunRow>,
|
||||
wooden_fish_work_profile: __sdk::TableUpdate<WoodenFishWorkProfileRow>,
|
||||
}
|
||||
|
||||
impl TryFrom<__ws::v2::TransactionUpdate> for DbUpdate {
|
||||
@@ -2660,6 +2760,24 @@ impl TryFrom<__ws::v2::TransactionUpdate> for DbUpdate {
|
||||
"visual_novel_work_profile" => db_update.visual_novel_work_profile.append(
|
||||
visual_novel_work_profile_table::parse_table_update(table_update)?,
|
||||
),
|
||||
"wooden_fish_agent_session" => db_update.wooden_fish_agent_session.append(
|
||||
wooden_fish_agent_session_table::parse_table_update(table_update)?,
|
||||
),
|
||||
"wooden_fish_event" => db_update
|
||||
.wooden_fish_event
|
||||
.append(wooden_fish_event_table::parse_table_update(table_update)?),
|
||||
"wooden_fish_gallery_card_view" => db_update.wooden_fish_gallery_card_view.append(
|
||||
wooden_fish_gallery_card_view_table::parse_table_update(table_update)?,
|
||||
),
|
||||
"wooden_fish_gallery_view" => db_update.wooden_fish_gallery_view.append(
|
||||
wooden_fish_gallery_view_table::parse_table_update(table_update)?,
|
||||
),
|
||||
"wooden_fish_runtime_run" => db_update.wooden_fish_runtime_run.append(
|
||||
wooden_fish_runtime_run_table::parse_table_update(table_update)?,
|
||||
),
|
||||
"wooden_fish_work_profile" => db_update.wooden_fish_work_profile.append(
|
||||
wooden_fish_work_profile_table::parse_table_update(table_update)?,
|
||||
),
|
||||
|
||||
unknown => {
|
||||
return Err(__sdk::InternalError::unknown_name(
|
||||
@@ -3159,6 +3277,27 @@ impl __sdk::DbUpdate for DbUpdate {
|
||||
&self.visual_novel_work_profile,
|
||||
)
|
||||
.with_updates_by_pk(|row| &row.profile_id);
|
||||
diff.wooden_fish_agent_session = cache
|
||||
.apply_diff_to_table::<WoodenFishAgentSessionRow>(
|
||||
"wooden_fish_agent_session",
|
||||
&self.wooden_fish_agent_session,
|
||||
)
|
||||
.with_updates_by_pk(|row| &row.session_id);
|
||||
diff.wooden_fish_event = cache
|
||||
.apply_diff_to_table::<WoodenFishEventRow>("wooden_fish_event", &self.wooden_fish_event)
|
||||
.with_updates_by_pk(|row| &row.event_id);
|
||||
diff.wooden_fish_runtime_run = cache
|
||||
.apply_diff_to_table::<WoodenFishRuntimeRunRow>(
|
||||
"wooden_fish_runtime_run",
|
||||
&self.wooden_fish_runtime_run,
|
||||
)
|
||||
.with_updates_by_pk(|row| &row.run_id);
|
||||
diff.wooden_fish_work_profile = cache
|
||||
.apply_diff_to_table::<WoodenFishWorkProfileRow>(
|
||||
"wooden_fish_work_profile",
|
||||
&self.wooden_fish_work_profile,
|
||||
)
|
||||
.with_updates_by_pk(|row| &row.profile_id);
|
||||
diff.big_fish_gallery_view = cache.apply_diff_to_table::<BigFishWorkSummarySnapshot>(
|
||||
"big_fish_gallery_view",
|
||||
&self.big_fish_gallery_view,
|
||||
@@ -3191,6 +3330,15 @@ impl __sdk::DbUpdate for DbUpdate {
|
||||
"visual_novel_gallery_view",
|
||||
&self.visual_novel_gallery_view,
|
||||
);
|
||||
diff.wooden_fish_gallery_card_view = cache
|
||||
.apply_diff_to_table::<WoodenFishGalleryCardViewRow>(
|
||||
"wooden_fish_gallery_card_view",
|
||||
&self.wooden_fish_gallery_card_view,
|
||||
);
|
||||
diff.wooden_fish_gallery_view = cache.apply_diff_to_table::<WoodenFishGalleryViewRow>(
|
||||
"wooden_fish_gallery_view",
|
||||
&self.wooden_fish_gallery_view,
|
||||
);
|
||||
|
||||
diff
|
||||
}
|
||||
@@ -3501,6 +3649,24 @@ impl __sdk::DbUpdate for DbUpdate {
|
||||
"visual_novel_work_profile" => db_update
|
||||
.visual_novel_work_profile
|
||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||
"wooden_fish_agent_session" => db_update
|
||||
.wooden_fish_agent_session
|
||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||
"wooden_fish_event" => db_update
|
||||
.wooden_fish_event
|
||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||
"wooden_fish_gallery_card_view" => db_update
|
||||
.wooden_fish_gallery_card_view
|
||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||
"wooden_fish_gallery_view" => db_update
|
||||
.wooden_fish_gallery_view
|
||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||
"wooden_fish_runtime_run" => db_update
|
||||
.wooden_fish_runtime_run
|
||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||
"wooden_fish_work_profile" => db_update
|
||||
.wooden_fish_work_profile
|
||||
.append(__sdk::parse_row_list_as_inserts(table_rows.rows)?),
|
||||
unknown => {
|
||||
return Err(
|
||||
__sdk::InternalError::unknown_name("table", unknown, "QueryRows").into(),
|
||||
@@ -3817,6 +3983,24 @@ impl __sdk::DbUpdate for DbUpdate {
|
||||
"visual_novel_work_profile" => db_update
|
||||
.visual_novel_work_profile
|
||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||
"wooden_fish_agent_session" => db_update
|
||||
.wooden_fish_agent_session
|
||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||
"wooden_fish_event" => db_update
|
||||
.wooden_fish_event
|
||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||
"wooden_fish_gallery_card_view" => db_update
|
||||
.wooden_fish_gallery_card_view
|
||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||
"wooden_fish_gallery_view" => db_update
|
||||
.wooden_fish_gallery_view
|
||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||
"wooden_fish_runtime_run" => db_update
|
||||
.wooden_fish_runtime_run
|
||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||
"wooden_fish_work_profile" => db_update
|
||||
.wooden_fish_work_profile
|
||||
.append(__sdk::parse_row_list_as_deletes(table_rows.rows)?),
|
||||
unknown => {
|
||||
return Err(
|
||||
__sdk::InternalError::unknown_name("table", unknown, "QueryRows").into(),
|
||||
@@ -3936,6 +4120,12 @@ pub struct AppliedDiff<'r> {
|
||||
__sdk::TableAppliedDiff<'r, VisualNovelRuntimeHistoryEntryRow>,
|
||||
visual_novel_runtime_run: __sdk::TableAppliedDiff<'r, VisualNovelRuntimeRunRow>,
|
||||
visual_novel_work_profile: __sdk::TableAppliedDiff<'r, VisualNovelWorkProfileRow>,
|
||||
wooden_fish_agent_session: __sdk::TableAppliedDiff<'r, WoodenFishAgentSessionRow>,
|
||||
wooden_fish_event: __sdk::TableAppliedDiff<'r, WoodenFishEventRow>,
|
||||
wooden_fish_gallery_card_view: __sdk::TableAppliedDiff<'r, WoodenFishGalleryCardViewRow>,
|
||||
wooden_fish_gallery_view: __sdk::TableAppliedDiff<'r, WoodenFishGalleryViewRow>,
|
||||
wooden_fish_runtime_run: __sdk::TableAppliedDiff<'r, WoodenFishRuntimeRunRow>,
|
||||
wooden_fish_work_profile: __sdk::TableAppliedDiff<'r, WoodenFishWorkProfileRow>,
|
||||
__unused: std::marker::PhantomData<&'r ()>,
|
||||
}
|
||||
|
||||
@@ -4434,6 +4624,36 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> {
|
||||
&self.visual_novel_work_profile,
|
||||
event,
|
||||
);
|
||||
callbacks.invoke_table_row_callbacks::<WoodenFishAgentSessionRow>(
|
||||
"wooden_fish_agent_session",
|
||||
&self.wooden_fish_agent_session,
|
||||
event,
|
||||
);
|
||||
callbacks.invoke_table_row_callbacks::<WoodenFishEventRow>(
|
||||
"wooden_fish_event",
|
||||
&self.wooden_fish_event,
|
||||
event,
|
||||
);
|
||||
callbacks.invoke_table_row_callbacks::<WoodenFishGalleryCardViewRow>(
|
||||
"wooden_fish_gallery_card_view",
|
||||
&self.wooden_fish_gallery_card_view,
|
||||
event,
|
||||
);
|
||||
callbacks.invoke_table_row_callbacks::<WoodenFishGalleryViewRow>(
|
||||
"wooden_fish_gallery_view",
|
||||
&self.wooden_fish_gallery_view,
|
||||
event,
|
||||
);
|
||||
callbacks.invoke_table_row_callbacks::<WoodenFishRuntimeRunRow>(
|
||||
"wooden_fish_runtime_run",
|
||||
&self.wooden_fish_runtime_run,
|
||||
event,
|
||||
);
|
||||
callbacks.invoke_table_row_callbacks::<WoodenFishWorkProfileRow>(
|
||||
"wooden_fish_work_profile",
|
||||
&self.wooden_fish_work_profile,
|
||||
event,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5195,6 +5415,12 @@ impl __sdk::SpacetimeModule for RemoteModule {
|
||||
visual_novel_runtime_history_entry_table::register_table(client_cache);
|
||||
visual_novel_runtime_run_table::register_table(client_cache);
|
||||
visual_novel_work_profile_table::register_table(client_cache);
|
||||
wooden_fish_agent_session_table::register_table(client_cache);
|
||||
wooden_fish_event_table::register_table(client_cache);
|
||||
wooden_fish_gallery_card_view_table::register_table(client_cache);
|
||||
wooden_fish_gallery_view_table::register_table(client_cache);
|
||||
wooden_fish_runtime_run_table::register_table(client_cache);
|
||||
wooden_fish_work_profile_table::register_table(client_cache);
|
||||
}
|
||||
const ALL_TABLE_NAMES: &'static [&'static str] = &[
|
||||
"ai_result_reference",
|
||||
@@ -5298,5 +5524,11 @@ impl __sdk::SpacetimeModule for RemoteModule {
|
||||
"visual_novel_runtime_history_entry",
|
||||
"visual_novel_runtime_run",
|
||||
"visual_novel_work_profile",
|
||||
"wooden_fish_agent_session",
|
||||
"wooden_fish_event",
|
||||
"wooden_fish_gallery_card_view",
|
||||
"wooden_fish_gallery_view",
|
||||
"wooden_fish_runtime_run",
|
||||
"wooden_fish_work_profile",
|
||||
];
|
||||
}
|
||||
|
||||
@@ -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::wooden_fish_run_checkpoint_input_type::WoodenFishRunCheckpointInput;
|
||||
use super::wooden_fish_run_procedure_result_type::WoodenFishRunProcedureResult;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct CheckpointWoodenFishRunArgs {
|
||||
pub input: WoodenFishRunCheckpointInput,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for CheckpointWoodenFishRunArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `checkpoint_wooden_fish_run`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait checkpoint_wooden_fish_run {
|
||||
fn checkpoint_wooden_fish_run(&self, input: WoodenFishRunCheckpointInput) {
|
||||
self.checkpoint_wooden_fish_run_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn checkpoint_wooden_fish_run_then(
|
||||
&self,
|
||||
input: WoodenFishRunCheckpointInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<WoodenFishRunProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl checkpoint_wooden_fish_run for super::RemoteProcedures {
|
||||
fn checkpoint_wooden_fish_run_then(
|
||||
&self,
|
||||
input: WoodenFishRunCheckpointInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<WoodenFishRunProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, WoodenFishRunProcedureResult>(
|
||||
"checkpoint_wooden_fish_run",
|
||||
CheckpointWoodenFishRunArgs { 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::wooden_fish_agent_session_procedure_result_type::WoodenFishAgentSessionProcedureResult;
|
||||
use super::wooden_fish_draft_compile_input_type::WoodenFishDraftCompileInput;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct CompileWoodenFishDraftArgs {
|
||||
pub input: WoodenFishDraftCompileInput,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for CompileWoodenFishDraftArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `compile_wooden_fish_draft`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait compile_wooden_fish_draft {
|
||||
fn compile_wooden_fish_draft(&self, input: WoodenFishDraftCompileInput) {
|
||||
self.compile_wooden_fish_draft_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn compile_wooden_fish_draft_then(
|
||||
&self,
|
||||
input: WoodenFishDraftCompileInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<WoodenFishAgentSessionProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl compile_wooden_fish_draft for super::RemoteProcedures {
|
||||
fn compile_wooden_fish_draft_then(
|
||||
&self,
|
||||
input: WoodenFishDraftCompileInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<WoodenFishAgentSessionProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, WoodenFishAgentSessionProcedureResult>(
|
||||
"compile_wooden_fish_draft",
|
||||
CompileWoodenFishDraftArgs { 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::wooden_fish_agent_session_create_input_type::WoodenFishAgentSessionCreateInput;
|
||||
use super::wooden_fish_agent_session_procedure_result_type::WoodenFishAgentSessionProcedureResult;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct CreateWoodenFishAgentSessionArgs {
|
||||
pub input: WoodenFishAgentSessionCreateInput,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for CreateWoodenFishAgentSessionArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `create_wooden_fish_agent_session`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait create_wooden_fish_agent_session {
|
||||
fn create_wooden_fish_agent_session(&self, input: WoodenFishAgentSessionCreateInput) {
|
||||
self.create_wooden_fish_agent_session_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn create_wooden_fish_agent_session_then(
|
||||
&self,
|
||||
input: WoodenFishAgentSessionCreateInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<WoodenFishAgentSessionProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl create_wooden_fish_agent_session for super::RemoteProcedures {
|
||||
fn create_wooden_fish_agent_session_then(
|
||||
&self,
|
||||
input: WoodenFishAgentSessionCreateInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<WoodenFishAgentSessionProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, WoodenFishAgentSessionProcedureResult>(
|
||||
"create_wooden_fish_agent_session",
|
||||
CreateWoodenFishAgentSessionArgs { 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::wooden_fish_run_finish_input_type::WoodenFishRunFinishInput;
|
||||
use super::wooden_fish_run_procedure_result_type::WoodenFishRunProcedureResult;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct FinishWoodenFishRunArgs {
|
||||
pub input: WoodenFishRunFinishInput,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for FinishWoodenFishRunArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `finish_wooden_fish_run`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait finish_wooden_fish_run {
|
||||
fn finish_wooden_fish_run(&self, input: WoodenFishRunFinishInput) {
|
||||
self.finish_wooden_fish_run_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn finish_wooden_fish_run_then(
|
||||
&self,
|
||||
input: WoodenFishRunFinishInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<WoodenFishRunProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl finish_wooden_fish_run for super::RemoteProcedures {
|
||||
fn finish_wooden_fish_run_then(
|
||||
&self,
|
||||
input: WoodenFishRunFinishInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<WoodenFishRunProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, WoodenFishRunProcedureResult>(
|
||||
"finish_wooden_fish_run",
|
||||
FinishWoodenFishRunArgs { input },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
// THIS FILE IS AUTOMATICALLY GENERATED BY SPACETIMEDB. EDITS TO THIS FILE
|
||||
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
|
||||
|
||||
|
||||
@@ -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::wooden_fish_agent_session_get_input_type::WoodenFishAgentSessionGetInput;
|
||||
use super::wooden_fish_agent_session_procedure_result_type::WoodenFishAgentSessionProcedureResult;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct GetWoodenFishAgentSessionArgs {
|
||||
pub input: WoodenFishAgentSessionGetInput,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for GetWoodenFishAgentSessionArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `get_wooden_fish_agent_session`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait get_wooden_fish_agent_session {
|
||||
fn get_wooden_fish_agent_session(&self, input: WoodenFishAgentSessionGetInput) {
|
||||
self.get_wooden_fish_agent_session_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn get_wooden_fish_agent_session_then(
|
||||
&self,
|
||||
input: WoodenFishAgentSessionGetInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<WoodenFishAgentSessionProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl get_wooden_fish_agent_session for super::RemoteProcedures {
|
||||
fn get_wooden_fish_agent_session_then(
|
||||
&self,
|
||||
input: WoodenFishAgentSessionGetInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<WoodenFishAgentSessionProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, WoodenFishAgentSessionProcedureResult>(
|
||||
"get_wooden_fish_agent_session",
|
||||
GetWoodenFishAgentSessionArgs { 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::wooden_fish_run_get_input_type::WoodenFishRunGetInput;
|
||||
use super::wooden_fish_run_procedure_result_type::WoodenFishRunProcedureResult;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct GetWoodenFishRunArgs {
|
||||
pub input: WoodenFishRunGetInput,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for GetWoodenFishRunArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `get_wooden_fish_run`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait get_wooden_fish_run {
|
||||
fn get_wooden_fish_run(&self, input: WoodenFishRunGetInput) {
|
||||
self.get_wooden_fish_run_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn get_wooden_fish_run_then(
|
||||
&self,
|
||||
input: WoodenFishRunGetInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<WoodenFishRunProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl get_wooden_fish_run for super::RemoteProcedures {
|
||||
fn get_wooden_fish_run_then(
|
||||
&self,
|
||||
input: WoodenFishRunGetInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<WoodenFishRunProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, WoodenFishRunProcedureResult>(
|
||||
"get_wooden_fish_run",
|
||||
GetWoodenFishRunArgs { 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::wooden_fish_work_get_input_type::WoodenFishWorkGetInput;
|
||||
use super::wooden_fish_work_procedure_result_type::WoodenFishWorkProcedureResult;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct GetWoodenFishWorkProfileArgs {
|
||||
pub input: WoodenFishWorkGetInput,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for GetWoodenFishWorkProfileArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `get_wooden_fish_work_profile`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait get_wooden_fish_work_profile {
|
||||
fn get_wooden_fish_work_profile(&self, input: WoodenFishWorkGetInput) {
|
||||
self.get_wooden_fish_work_profile_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn get_wooden_fish_work_profile_then(
|
||||
&self,
|
||||
input: WoodenFishWorkGetInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<WoodenFishWorkProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl get_wooden_fish_work_profile for super::RemoteProcedures {
|
||||
fn get_wooden_fish_work_profile_then(
|
||||
&self,
|
||||
input: WoodenFishWorkGetInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<WoodenFishWorkProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, WoodenFishWorkProcedureResult>(
|
||||
"get_wooden_fish_work_profile",
|
||||
GetWoodenFishWorkProfileArgs { 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::wooden_fish_works_list_input_type::WoodenFishWorksListInput;
|
||||
use super::wooden_fish_works_procedure_result_type::WoodenFishWorksProcedureResult;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct ListWoodenFishWorksArgs {
|
||||
pub input: WoodenFishWorksListInput,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for ListWoodenFishWorksArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `list_wooden_fish_works`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait list_wooden_fish_works {
|
||||
fn list_wooden_fish_works(&self, input: WoodenFishWorksListInput) {
|
||||
self.list_wooden_fish_works_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn list_wooden_fish_works_then(
|
||||
&self,
|
||||
input: WoodenFishWorksListInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<WoodenFishWorksProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl list_wooden_fish_works for super::RemoteProcedures {
|
||||
fn list_wooden_fish_works_then(
|
||||
&self,
|
||||
input: WoodenFishWorksListInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<WoodenFishWorksProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, WoodenFishWorksProcedureResult>(
|
||||
"list_wooden_fish_works",
|
||||
ListWoodenFishWorksArgs { 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::wooden_fish_work_procedure_result_type::WoodenFishWorkProcedureResult;
|
||||
use super::wooden_fish_work_publish_input_type::WoodenFishWorkPublishInput;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct PublishWoodenFishWorkArgs {
|
||||
pub input: WoodenFishWorkPublishInput,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for PublishWoodenFishWorkArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `publish_wooden_fish_work`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait publish_wooden_fish_work {
|
||||
fn publish_wooden_fish_work(&self, input: WoodenFishWorkPublishInput) {
|
||||
self.publish_wooden_fish_work_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn publish_wooden_fish_work_then(
|
||||
&self,
|
||||
input: WoodenFishWorkPublishInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<WoodenFishWorkProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl publish_wooden_fish_work for super::RemoteProcedures {
|
||||
fn publish_wooden_fish_work_then(
|
||||
&self,
|
||||
input: WoodenFishWorkPublishInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<WoodenFishWorkProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, WoodenFishWorkProcedureResult>(
|
||||
"publish_wooden_fish_work",
|
||||
PublishWoodenFishWorkArgs { 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::wooden_fish_run_procedure_result_type::WoodenFishRunProcedureResult;
|
||||
use super::wooden_fish_run_start_input_type::WoodenFishRunStartInput;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct StartWoodenFishRunArgs {
|
||||
pub input: WoodenFishRunStartInput,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for StartWoodenFishRunArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `start_wooden_fish_run`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait start_wooden_fish_run {
|
||||
fn start_wooden_fish_run(&self, input: WoodenFishRunStartInput) {
|
||||
self.start_wooden_fish_run_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn start_wooden_fish_run_then(
|
||||
&self,
|
||||
input: WoodenFishRunStartInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<WoodenFishRunProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl start_wooden_fish_run for super::RemoteProcedures {
|
||||
fn start_wooden_fish_run_then(
|
||||
&self,
|
||||
input: WoodenFishRunStartInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<WoodenFishRunProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, WoodenFishRunProcedureResult>(
|
||||
"start_wooden_fish_run",
|
||||
StartWoodenFishRunArgs { 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::wooden_fish_work_procedure_result_type::WoodenFishWorkProcedureResult;
|
||||
use super::wooden_fish_work_update_input_type::WoodenFishWorkUpdateInput;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
struct UpdateWoodenFishWorkArgs {
|
||||
pub input: WoodenFishWorkUpdateInput,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for UpdateWoodenFishWorkArgs {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the procedure `update_wooden_fish_work`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteProcedures`].
|
||||
pub trait update_wooden_fish_work {
|
||||
fn update_wooden_fish_work(&self, input: WoodenFishWorkUpdateInput) {
|
||||
self.update_wooden_fish_work_then(input, |_, _| {});
|
||||
}
|
||||
|
||||
fn update_wooden_fish_work_then(
|
||||
&self,
|
||||
input: WoodenFishWorkUpdateInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<WoodenFishWorkProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
);
|
||||
}
|
||||
|
||||
impl update_wooden_fish_work for super::RemoteProcedures {
|
||||
fn update_wooden_fish_work_then(
|
||||
&self,
|
||||
input: WoodenFishWorkUpdateInput,
|
||||
|
||||
__callback: impl FnOnce(
|
||||
&super::ProcedureEventContext,
|
||||
Result<WoodenFishWorkProcedureResult, __sdk::InternalError>,
|
||||
) + Send
|
||||
+ 'static,
|
||||
) {
|
||||
self.imp
|
||||
.invoke_procedure_with_callback::<_, WoodenFishWorkProcedureResult>(
|
||||
"update_wooden_fish_work",
|
||||
UpdateWoodenFishWorkArgs { input },
|
||||
__callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// 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 WoodenFishAgentSessionCreateInput {
|
||||
pub session_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub work_title: String,
|
||||
pub work_description: String,
|
||||
pub theme_tags_json: Option<String>,
|
||||
pub config_json: Option<String>,
|
||||
pub draft_json: Option<String>,
|
||||
pub created_at_micros: i64,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishAgentSessionCreateInput {
|
||||
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 WoodenFishAgentSessionGetInput {
|
||||
pub session_id: String,
|
||||
pub owner_user_id: String,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishAgentSessionGetInput {
|
||||
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};
|
||||
|
||||
use super::wooden_fish_agent_session_snapshot_type::WoodenFishAgentSessionSnapshot;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
pub struct WoodenFishAgentSessionProcedureResult {
|
||||
pub ok: bool,
|
||||
pub session: Option<WoodenFishAgentSessionSnapshot>,
|
||||
pub error_message: Option<String>,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishAgentSessionProcedureResult {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
// 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 WoodenFishAgentSessionRow {
|
||||
pub session_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub current_turn: u32,
|
||||
pub progress_percent: u32,
|
||||
pub stage: String,
|
||||
pub config_json: String,
|
||||
pub draft_json: String,
|
||||
pub published_profile_id: String,
|
||||
pub created_at: __sdk::Timestamp,
|
||||
pub updated_at: __sdk::Timestamp,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishAgentSessionRow {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
/// Column accessor struct for the table `WoodenFishAgentSessionRow`.
|
||||
///
|
||||
/// Provides typed access to columns for query building.
|
||||
pub struct WoodenFishAgentSessionRowCols {
|
||||
pub session_id: __sdk::__query_builder::Col<WoodenFishAgentSessionRow, String>,
|
||||
pub owner_user_id: __sdk::__query_builder::Col<WoodenFishAgentSessionRow, String>,
|
||||
pub current_turn: __sdk::__query_builder::Col<WoodenFishAgentSessionRow, u32>,
|
||||
pub progress_percent: __sdk::__query_builder::Col<WoodenFishAgentSessionRow, u32>,
|
||||
pub stage: __sdk::__query_builder::Col<WoodenFishAgentSessionRow, String>,
|
||||
pub config_json: __sdk::__query_builder::Col<WoodenFishAgentSessionRow, String>,
|
||||
pub draft_json: __sdk::__query_builder::Col<WoodenFishAgentSessionRow, String>,
|
||||
pub published_profile_id: __sdk::__query_builder::Col<WoodenFishAgentSessionRow, String>,
|
||||
pub created_at: __sdk::__query_builder::Col<WoodenFishAgentSessionRow, __sdk::Timestamp>,
|
||||
pub updated_at: __sdk::__query_builder::Col<WoodenFishAgentSessionRow, __sdk::Timestamp>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasCols for WoodenFishAgentSessionRow {
|
||||
type Cols = WoodenFishAgentSessionRowCols;
|
||||
fn cols(table_name: &'static str) -> Self::Cols {
|
||||
WoodenFishAgentSessionRowCols {
|
||||
session_id: __sdk::__query_builder::Col::new(table_name, "session_id"),
|
||||
owner_user_id: __sdk::__query_builder::Col::new(table_name, "owner_user_id"),
|
||||
current_turn: __sdk::__query_builder::Col::new(table_name, "current_turn"),
|
||||
progress_percent: __sdk::__query_builder::Col::new(table_name, "progress_percent"),
|
||||
stage: __sdk::__query_builder::Col::new(table_name, "stage"),
|
||||
config_json: __sdk::__query_builder::Col::new(table_name, "config_json"),
|
||||
draft_json: __sdk::__query_builder::Col::new(table_name, "draft_json"),
|
||||
published_profile_id: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"published_profile_id",
|
||||
),
|
||||
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 `WoodenFishAgentSessionRow`.
|
||||
///
|
||||
/// Provides typed access to indexed columns for query building.
|
||||
pub struct WoodenFishAgentSessionRowIxCols {
|
||||
pub owner_user_id: __sdk::__query_builder::IxCol<WoodenFishAgentSessionRow, String>,
|
||||
pub session_id: __sdk::__query_builder::IxCol<WoodenFishAgentSessionRow, String>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasIxCols for WoodenFishAgentSessionRow {
|
||||
type IxCols = WoodenFishAgentSessionRowIxCols;
|
||||
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
||||
WoodenFishAgentSessionRowIxCols {
|
||||
owner_user_id: __sdk::__query_builder::IxCol::new(table_name, "owner_user_id"),
|
||||
session_id: __sdk::__query_builder::IxCol::new(table_name, "session_id"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::CanBeLookupTable for WoodenFishAgentSessionRow {}
|
||||
@@ -0,0 +1,27 @@
|
||||
// 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::wooden_fish_creator_config_snapshot_type::WoodenFishCreatorConfigSnapshot;
|
||||
use super::wooden_fish_draft_snapshot_type::WoodenFishDraftSnapshot;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
pub struct WoodenFishAgentSessionSnapshot {
|
||||
pub session_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub current_turn: u32,
|
||||
pub progress_percent: u32,
|
||||
pub stage: String,
|
||||
pub config: WoodenFishCreatorConfigSnapshot,
|
||||
pub draft: Option<WoodenFishDraftSnapshot>,
|
||||
pub published_profile_id: Option<String>,
|
||||
pub created_at_micros: i64,
|
||||
pub updated_at_micros: i64,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishAgentSessionSnapshot {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
// 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::wooden_fish_agent_session_row_type::WoodenFishAgentSessionRow;
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
/// Table handle for the table `wooden_fish_agent_session`.
|
||||
///
|
||||
/// Obtain a handle from the [`WoodenFishAgentSessionTableAccess::wooden_fish_agent_session`] method on [`super::RemoteTables`],
|
||||
/// like `ctx.db.wooden_fish_agent_session()`.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.wooden_fish_agent_session().on_insert(...)`.
|
||||
pub struct WoodenFishAgentSessionTableHandle<'ctx> {
|
||||
imp: __sdk::TableHandle<WoodenFishAgentSessionRow>,
|
||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the table `wooden_fish_agent_session`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteTables`].
|
||||
pub trait WoodenFishAgentSessionTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Obtain a [`WoodenFishAgentSessionTableHandle`], which mediates access to the table `wooden_fish_agent_session`.
|
||||
fn wooden_fish_agent_session(&self) -> WoodenFishAgentSessionTableHandle<'_>;
|
||||
}
|
||||
|
||||
impl WoodenFishAgentSessionTableAccess for super::RemoteTables {
|
||||
fn wooden_fish_agent_session(&self) -> WoodenFishAgentSessionTableHandle<'_> {
|
||||
WoodenFishAgentSessionTableHandle {
|
||||
imp: self
|
||||
.imp
|
||||
.get_table::<WoodenFishAgentSessionRow>("wooden_fish_agent_session"),
|
||||
ctx: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WoodenFishAgentSessionInsertCallbackId(__sdk::CallbackId);
|
||||
pub struct WoodenFishAgentSessionDeleteCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::Table for WoodenFishAgentSessionTableHandle<'ctx> {
|
||||
type Row = WoodenFishAgentSessionRow;
|
||||
type EventContext = super::EventContext;
|
||||
|
||||
fn count(&self) -> u64 {
|
||||
self.imp.count()
|
||||
}
|
||||
fn iter(&self) -> impl Iterator<Item = WoodenFishAgentSessionRow> + '_ {
|
||||
self.imp.iter()
|
||||
}
|
||||
|
||||
type InsertCallbackId = WoodenFishAgentSessionInsertCallbackId;
|
||||
|
||||
fn on_insert(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> WoodenFishAgentSessionInsertCallbackId {
|
||||
WoodenFishAgentSessionInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_insert(&self, callback: WoodenFishAgentSessionInsertCallbackId) {
|
||||
self.imp.remove_on_insert(callback.0)
|
||||
}
|
||||
|
||||
type DeleteCallbackId = WoodenFishAgentSessionDeleteCallbackId;
|
||||
|
||||
fn on_delete(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> WoodenFishAgentSessionDeleteCallbackId {
|
||||
WoodenFishAgentSessionDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_delete(&self, callback: WoodenFishAgentSessionDeleteCallbackId) {
|
||||
self.imp.remove_on_delete(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WoodenFishAgentSessionUpdateCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::TableWithPrimaryKey for WoodenFishAgentSessionTableHandle<'ctx> {
|
||||
type UpdateCallbackId = WoodenFishAgentSessionUpdateCallbackId;
|
||||
|
||||
fn on_update(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||
) -> WoodenFishAgentSessionUpdateCallbackId {
|
||||
WoodenFishAgentSessionUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_update(&self, callback: WoodenFishAgentSessionUpdateCallbackId) {
|
||||
self.imp.remove_on_update(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Access to the `session_id` unique index on the table `wooden_fish_agent_session`,
|
||||
/// which allows point queries on the field of the same name
|
||||
/// via the [`WoodenFishAgentSessionSessionIdUnique::find`] method.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.wooden_fish_agent_session().session_id().find(...)`.
|
||||
pub struct WoodenFishAgentSessionSessionIdUnique<'ctx> {
|
||||
imp: __sdk::UniqueConstraintHandle<WoodenFishAgentSessionRow, String>,
|
||||
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
impl<'ctx> WoodenFishAgentSessionTableHandle<'ctx> {
|
||||
/// Get a handle on the `session_id` unique index on the table `wooden_fish_agent_session`.
|
||||
pub fn session_id(&self) -> WoodenFishAgentSessionSessionIdUnique<'ctx> {
|
||||
WoodenFishAgentSessionSessionIdUnique {
|
||||
imp: self.imp.get_unique_constraint::<String>("session_id"),
|
||||
phantom: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> WoodenFishAgentSessionSessionIdUnique<'ctx> {
|
||||
/// Find the subscribed row whose `session_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<WoodenFishAgentSessionRow> {
|
||||
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::<WoodenFishAgentSessionRow>("wooden_fish_agent_session");
|
||||
_table.add_unique_constraint::<String>("session_id", |row| &row.session_id);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn parse_table_update(
|
||||
raw_updates: __ws::v2::TableUpdate,
|
||||
) -> __sdk::Result<__sdk::TableUpdate<WoodenFishAgentSessionRow>> {
|
||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||
__sdk::InternalError::failed_parse("TableUpdate<WoodenFishAgentSessionRow>", "TableUpdate")
|
||||
.with_cause(e)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for query builder access to the table `WoodenFishAgentSessionRow`.
|
||||
///
|
||||
/// Implemented for [`__sdk::QueryTableAccessor`].
|
||||
pub trait wooden_fish_agent_sessionQueryTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Get a query builder for the table `WoodenFishAgentSessionRow`.
|
||||
fn wooden_fish_agent_session(&self)
|
||||
-> __sdk::__query_builder::Table<WoodenFishAgentSessionRow>;
|
||||
}
|
||||
|
||||
impl wooden_fish_agent_sessionQueryTableAccess for __sdk::QueryTableAccessor {
|
||||
fn wooden_fish_agent_session(
|
||||
&self,
|
||||
) -> __sdk::__query_builder::Table<WoodenFishAgentSessionRow> {
|
||||
__sdk::__query_builder::Table::new("wooden_fish_agent_session")
|
||||
}
|
||||
}
|
||||
@@ -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 WoodenFishAudioAssetSnapshot {
|
||||
pub asset_id: String,
|
||||
pub audio_src: String,
|
||||
pub audio_object_key: String,
|
||||
pub asset_object_id: String,
|
||||
pub source: String,
|
||||
pub prompt: Option<String>,
|
||||
pub duration_ms: Option<u32>,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishAudioAssetSnapshot {
|
||||
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 WoodenFishCreatorConfigSnapshot {
|
||||
pub work_title: String,
|
||||
pub work_description: String,
|
||||
pub theme_tags: Vec<String>,
|
||||
pub hit_object_prompt: String,
|
||||
pub hit_object_reference_image_src: Option<String>,
|
||||
pub hit_sound_prompt: Option<String>,
|
||||
pub floating_words: Vec<String>,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishCreatorConfigSnapshot {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -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 WoodenFishDraftCompileInput {
|
||||
pub session_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub profile_id: String,
|
||||
pub author_display_name: String,
|
||||
pub work_title: String,
|
||||
pub work_description: String,
|
||||
pub theme_tags_json: Option<String>,
|
||||
pub hit_object_prompt: String,
|
||||
pub hit_object_reference_image_src: Option<String>,
|
||||
pub hit_sound_prompt: Option<String>,
|
||||
pub hit_object_asset_json: Option<String>,
|
||||
pub hit_sound_asset_json: Option<String>,
|
||||
pub floating_words_json: Option<String>,
|
||||
pub cover_image_src: Option<String>,
|
||||
pub generation_status: Option<String>,
|
||||
pub compiled_at_micros: i64,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishDraftCompileInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// 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::wooden_fish_audio_asset_snapshot_type::WoodenFishAudioAssetSnapshot;
|
||||
use super::wooden_fish_image_asset_snapshot_type::WoodenFishImageAssetSnapshot;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
pub struct WoodenFishDraftSnapshot {
|
||||
pub template_id: String,
|
||||
pub template_name: String,
|
||||
pub profile_id: Option<String>,
|
||||
pub work_title: String,
|
||||
pub work_description: String,
|
||||
pub theme_tags: Vec<String>,
|
||||
pub hit_object_prompt: String,
|
||||
pub hit_object_reference_image_src: Option<String>,
|
||||
pub hit_sound_prompt: Option<String>,
|
||||
pub floating_words: Vec<String>,
|
||||
pub hit_object_asset: Option<WoodenFishImageAssetSnapshot>,
|
||||
pub hit_sound_asset: Option<WoodenFishAudioAssetSnapshot>,
|
||||
pub cover_image_src: Option<String>,
|
||||
pub generation_status: String,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishDraftSnapshot {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// 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 WoodenFishEventRow {
|
||||
pub event_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub profile_id: String,
|
||||
pub run_id: String,
|
||||
pub event_type: String,
|
||||
pub result: String,
|
||||
pub occurred_at: __sdk::Timestamp,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishEventRow {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
/// Column accessor struct for the table `WoodenFishEventRow`.
|
||||
///
|
||||
/// Provides typed access to columns for query building.
|
||||
pub struct WoodenFishEventRowCols {
|
||||
pub event_id: __sdk::__query_builder::Col<WoodenFishEventRow, String>,
|
||||
pub owner_user_id: __sdk::__query_builder::Col<WoodenFishEventRow, String>,
|
||||
pub profile_id: __sdk::__query_builder::Col<WoodenFishEventRow, String>,
|
||||
pub run_id: __sdk::__query_builder::Col<WoodenFishEventRow, String>,
|
||||
pub event_type: __sdk::__query_builder::Col<WoodenFishEventRow, String>,
|
||||
pub result: __sdk::__query_builder::Col<WoodenFishEventRow, String>,
|
||||
pub occurred_at: __sdk::__query_builder::Col<WoodenFishEventRow, __sdk::Timestamp>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasCols for WoodenFishEventRow {
|
||||
type Cols = WoodenFishEventRowCols;
|
||||
fn cols(table_name: &'static str) -> Self::Cols {
|
||||
WoodenFishEventRowCols {
|
||||
event_id: __sdk::__query_builder::Col::new(table_name, "event_id"),
|
||||
owner_user_id: __sdk::__query_builder::Col::new(table_name, "owner_user_id"),
|
||||
profile_id: __sdk::__query_builder::Col::new(table_name, "profile_id"),
|
||||
run_id: __sdk::__query_builder::Col::new(table_name, "run_id"),
|
||||
event_type: __sdk::__query_builder::Col::new(table_name, "event_type"),
|
||||
result: __sdk::__query_builder::Col::new(table_name, "result"),
|
||||
occurred_at: __sdk::__query_builder::Col::new(table_name, "occurred_at"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Indexed column accessor struct for the table `WoodenFishEventRow`.
|
||||
///
|
||||
/// Provides typed access to indexed columns for query building.
|
||||
pub struct WoodenFishEventRowIxCols {
|
||||
pub event_id: __sdk::__query_builder::IxCol<WoodenFishEventRow, String>,
|
||||
pub profile_id: __sdk::__query_builder::IxCol<WoodenFishEventRow, String>,
|
||||
pub run_id: __sdk::__query_builder::IxCol<WoodenFishEventRow, String>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasIxCols for WoodenFishEventRow {
|
||||
type IxCols = WoodenFishEventRowIxCols;
|
||||
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
||||
WoodenFishEventRowIxCols {
|
||||
event_id: __sdk::__query_builder::IxCol::new(table_name, "event_id"),
|
||||
profile_id: __sdk::__query_builder::IxCol::new(table_name, "profile_id"),
|
||||
run_id: __sdk::__query_builder::IxCol::new(table_name, "run_id"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::CanBeLookupTable for WoodenFishEventRow {}
|
||||
@@ -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::wooden_fish_event_row_type::WoodenFishEventRow;
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
/// Table handle for the table `wooden_fish_event`.
|
||||
///
|
||||
/// Obtain a handle from the [`WoodenFishEventTableAccess::wooden_fish_event`] method on [`super::RemoteTables`],
|
||||
/// like `ctx.db.wooden_fish_event()`.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.wooden_fish_event().on_insert(...)`.
|
||||
pub struct WoodenFishEventTableHandle<'ctx> {
|
||||
imp: __sdk::TableHandle<WoodenFishEventRow>,
|
||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the table `wooden_fish_event`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteTables`].
|
||||
pub trait WoodenFishEventTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Obtain a [`WoodenFishEventTableHandle`], which mediates access to the table `wooden_fish_event`.
|
||||
fn wooden_fish_event(&self) -> WoodenFishEventTableHandle<'_>;
|
||||
}
|
||||
|
||||
impl WoodenFishEventTableAccess for super::RemoteTables {
|
||||
fn wooden_fish_event(&self) -> WoodenFishEventTableHandle<'_> {
|
||||
WoodenFishEventTableHandle {
|
||||
imp: self
|
||||
.imp
|
||||
.get_table::<WoodenFishEventRow>("wooden_fish_event"),
|
||||
ctx: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WoodenFishEventInsertCallbackId(__sdk::CallbackId);
|
||||
pub struct WoodenFishEventDeleteCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::Table for WoodenFishEventTableHandle<'ctx> {
|
||||
type Row = WoodenFishEventRow;
|
||||
type EventContext = super::EventContext;
|
||||
|
||||
fn count(&self) -> u64 {
|
||||
self.imp.count()
|
||||
}
|
||||
fn iter(&self) -> impl Iterator<Item = WoodenFishEventRow> + '_ {
|
||||
self.imp.iter()
|
||||
}
|
||||
|
||||
type InsertCallbackId = WoodenFishEventInsertCallbackId;
|
||||
|
||||
fn on_insert(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> WoodenFishEventInsertCallbackId {
|
||||
WoodenFishEventInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_insert(&self, callback: WoodenFishEventInsertCallbackId) {
|
||||
self.imp.remove_on_insert(callback.0)
|
||||
}
|
||||
|
||||
type DeleteCallbackId = WoodenFishEventDeleteCallbackId;
|
||||
|
||||
fn on_delete(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> WoodenFishEventDeleteCallbackId {
|
||||
WoodenFishEventDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_delete(&self, callback: WoodenFishEventDeleteCallbackId) {
|
||||
self.imp.remove_on_delete(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WoodenFishEventUpdateCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::TableWithPrimaryKey for WoodenFishEventTableHandle<'ctx> {
|
||||
type UpdateCallbackId = WoodenFishEventUpdateCallbackId;
|
||||
|
||||
fn on_update(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||
) -> WoodenFishEventUpdateCallbackId {
|
||||
WoodenFishEventUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_update(&self, callback: WoodenFishEventUpdateCallbackId) {
|
||||
self.imp.remove_on_update(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Access to the `event_id` unique index on the table `wooden_fish_event`,
|
||||
/// which allows point queries on the field of the same name
|
||||
/// via the [`WoodenFishEventEventIdUnique::find`] method.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.wooden_fish_event().event_id().find(...)`.
|
||||
pub struct WoodenFishEventEventIdUnique<'ctx> {
|
||||
imp: __sdk::UniqueConstraintHandle<WoodenFishEventRow, String>,
|
||||
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
impl<'ctx> WoodenFishEventTableHandle<'ctx> {
|
||||
/// Get a handle on the `event_id` unique index on the table `wooden_fish_event`.
|
||||
pub fn event_id(&self) -> WoodenFishEventEventIdUnique<'ctx> {
|
||||
WoodenFishEventEventIdUnique {
|
||||
imp: self.imp.get_unique_constraint::<String>("event_id"),
|
||||
phantom: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> WoodenFishEventEventIdUnique<'ctx> {
|
||||
/// Find the subscribed row whose `event_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<WoodenFishEventRow> {
|
||||
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::<WoodenFishEventRow>("wooden_fish_event");
|
||||
_table.add_unique_constraint::<String>("event_id", |row| &row.event_id);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn parse_table_update(
|
||||
raw_updates: __ws::v2::TableUpdate,
|
||||
) -> __sdk::Result<__sdk::TableUpdate<WoodenFishEventRow>> {
|
||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||
__sdk::InternalError::failed_parse("TableUpdate<WoodenFishEventRow>", "TableUpdate")
|
||||
.with_cause(e)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for query builder access to the table `WoodenFishEventRow`.
|
||||
///
|
||||
/// Implemented for [`__sdk::QueryTableAccessor`].
|
||||
pub trait wooden_fish_eventQueryTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Get a query builder for the table `WoodenFishEventRow`.
|
||||
fn wooden_fish_event(&self) -> __sdk::__query_builder::Table<WoodenFishEventRow>;
|
||||
}
|
||||
|
||||
impl wooden_fish_eventQueryTableAccess for __sdk::QueryTableAccessor {
|
||||
fn wooden_fish_event(&self) -> __sdk::__query_builder::Table<WoodenFishEventRow> {
|
||||
__sdk::__query_builder::Table::new("wooden_fish_event")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
// 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 WoodenFishGalleryCardViewRow {
|
||||
pub public_work_code: String,
|
||||
pub work_id: String,
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub author_display_name: String,
|
||||
pub work_title: String,
|
||||
pub work_description: String,
|
||||
pub cover_image_src: String,
|
||||
pub theme_tags: Vec<String>,
|
||||
pub publication_status: String,
|
||||
pub play_count: u32,
|
||||
pub updated_at_micros: i64,
|
||||
pub published_at_micros: Option<i64>,
|
||||
pub generation_status: String,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishGalleryCardViewRow {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
/// Column accessor struct for the table `WoodenFishGalleryCardViewRow`.
|
||||
///
|
||||
/// Provides typed access to columns for query building.
|
||||
pub struct WoodenFishGalleryCardViewRowCols {
|
||||
pub public_work_code: __sdk::__query_builder::Col<WoodenFishGalleryCardViewRow, String>,
|
||||
pub work_id: __sdk::__query_builder::Col<WoodenFishGalleryCardViewRow, String>,
|
||||
pub profile_id: __sdk::__query_builder::Col<WoodenFishGalleryCardViewRow, String>,
|
||||
pub owner_user_id: __sdk::__query_builder::Col<WoodenFishGalleryCardViewRow, String>,
|
||||
pub author_display_name: __sdk::__query_builder::Col<WoodenFishGalleryCardViewRow, String>,
|
||||
pub work_title: __sdk::__query_builder::Col<WoodenFishGalleryCardViewRow, String>,
|
||||
pub work_description: __sdk::__query_builder::Col<WoodenFishGalleryCardViewRow, String>,
|
||||
pub cover_image_src: __sdk::__query_builder::Col<WoodenFishGalleryCardViewRow, String>,
|
||||
pub theme_tags: __sdk::__query_builder::Col<WoodenFishGalleryCardViewRow, Vec<String>>,
|
||||
pub publication_status: __sdk::__query_builder::Col<WoodenFishGalleryCardViewRow, String>,
|
||||
pub play_count: __sdk::__query_builder::Col<WoodenFishGalleryCardViewRow, u32>,
|
||||
pub updated_at_micros: __sdk::__query_builder::Col<WoodenFishGalleryCardViewRow, i64>,
|
||||
pub published_at_micros: __sdk::__query_builder::Col<WoodenFishGalleryCardViewRow, Option<i64>>,
|
||||
pub generation_status: __sdk::__query_builder::Col<WoodenFishGalleryCardViewRow, String>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasCols for WoodenFishGalleryCardViewRow {
|
||||
type Cols = WoodenFishGalleryCardViewRowCols;
|
||||
fn cols(table_name: &'static str) -> Self::Cols {
|
||||
WoodenFishGalleryCardViewRowCols {
|
||||
public_work_code: __sdk::__query_builder::Col::new(table_name, "public_work_code"),
|
||||
work_id: __sdk::__query_builder::Col::new(table_name, "work_id"),
|
||||
profile_id: __sdk::__query_builder::Col::new(table_name, "profile_id"),
|
||||
owner_user_id: __sdk::__query_builder::Col::new(table_name, "owner_user_id"),
|
||||
author_display_name: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"author_display_name",
|
||||
),
|
||||
work_title: __sdk::__query_builder::Col::new(table_name, "work_title"),
|
||||
work_description: __sdk::__query_builder::Col::new(table_name, "work_description"),
|
||||
cover_image_src: __sdk::__query_builder::Col::new(table_name, "cover_image_src"),
|
||||
theme_tags: __sdk::__query_builder::Col::new(table_name, "theme_tags"),
|
||||
publication_status: __sdk::__query_builder::Col::new(table_name, "publication_status"),
|
||||
play_count: __sdk::__query_builder::Col::new(table_name, "play_count"),
|
||||
updated_at_micros: __sdk::__query_builder::Col::new(table_name, "updated_at_micros"),
|
||||
published_at_micros: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"published_at_micros",
|
||||
),
|
||||
generation_status: __sdk::__query_builder::Col::new(table_name, "generation_status"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
// 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::wooden_fish_gallery_card_view_row_type::WoodenFishGalleryCardViewRow;
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
/// Table handle for the table `wooden_fish_gallery_card_view`.
|
||||
///
|
||||
/// Obtain a handle from the [`WoodenFishGalleryCardViewTableAccess::wooden_fish_gallery_card_view`] method on [`super::RemoteTables`],
|
||||
/// like `ctx.db.wooden_fish_gallery_card_view()`.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.wooden_fish_gallery_card_view().on_insert(...)`.
|
||||
pub struct WoodenFishGalleryCardViewTableHandle<'ctx> {
|
||||
imp: __sdk::TableHandle<WoodenFishGalleryCardViewRow>,
|
||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the table `wooden_fish_gallery_card_view`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteTables`].
|
||||
pub trait WoodenFishGalleryCardViewTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Obtain a [`WoodenFishGalleryCardViewTableHandle`], which mediates access to the table `wooden_fish_gallery_card_view`.
|
||||
fn wooden_fish_gallery_card_view(&self) -> WoodenFishGalleryCardViewTableHandle<'_>;
|
||||
}
|
||||
|
||||
impl WoodenFishGalleryCardViewTableAccess for super::RemoteTables {
|
||||
fn wooden_fish_gallery_card_view(&self) -> WoodenFishGalleryCardViewTableHandle<'_> {
|
||||
WoodenFishGalleryCardViewTableHandle {
|
||||
imp: self
|
||||
.imp
|
||||
.get_table::<WoodenFishGalleryCardViewRow>("wooden_fish_gallery_card_view"),
|
||||
ctx: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WoodenFishGalleryCardViewInsertCallbackId(__sdk::CallbackId);
|
||||
pub struct WoodenFishGalleryCardViewDeleteCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::Table for WoodenFishGalleryCardViewTableHandle<'ctx> {
|
||||
type Row = WoodenFishGalleryCardViewRow;
|
||||
type EventContext = super::EventContext;
|
||||
|
||||
fn count(&self) -> u64 {
|
||||
self.imp.count()
|
||||
}
|
||||
fn iter(&self) -> impl Iterator<Item = WoodenFishGalleryCardViewRow> + '_ {
|
||||
self.imp.iter()
|
||||
}
|
||||
|
||||
type InsertCallbackId = WoodenFishGalleryCardViewInsertCallbackId;
|
||||
|
||||
fn on_insert(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> WoodenFishGalleryCardViewInsertCallbackId {
|
||||
WoodenFishGalleryCardViewInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_insert(&self, callback: WoodenFishGalleryCardViewInsertCallbackId) {
|
||||
self.imp.remove_on_insert(callback.0)
|
||||
}
|
||||
|
||||
type DeleteCallbackId = WoodenFishGalleryCardViewDeleteCallbackId;
|
||||
|
||||
fn on_delete(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> WoodenFishGalleryCardViewDeleteCallbackId {
|
||||
WoodenFishGalleryCardViewDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_delete(&self, callback: WoodenFishGalleryCardViewDeleteCallbackId) {
|
||||
self.imp.remove_on_delete(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
||||
let _table = client_cache
|
||||
.get_or_make_table::<WoodenFishGalleryCardViewRow>("wooden_fish_gallery_card_view");
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn parse_table_update(
|
||||
raw_updates: __ws::v2::TableUpdate,
|
||||
) -> __sdk::Result<__sdk::TableUpdate<WoodenFishGalleryCardViewRow>> {
|
||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||
__sdk::InternalError::failed_parse(
|
||||
"TableUpdate<WoodenFishGalleryCardViewRow>",
|
||||
"TableUpdate",
|
||||
)
|
||||
.with_cause(e)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for query builder access to the table `WoodenFishGalleryCardViewRow`.
|
||||
///
|
||||
/// Implemented for [`__sdk::QueryTableAccessor`].
|
||||
pub trait wooden_fish_gallery_card_viewQueryTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Get a query builder for the table `WoodenFishGalleryCardViewRow`.
|
||||
fn wooden_fish_gallery_card_view(
|
||||
&self,
|
||||
) -> __sdk::__query_builder::Table<WoodenFishGalleryCardViewRow>;
|
||||
}
|
||||
|
||||
impl wooden_fish_gallery_card_viewQueryTableAccess for __sdk::QueryTableAccessor {
|
||||
fn wooden_fish_gallery_card_view(
|
||||
&self,
|
||||
) -> __sdk::__query_builder::Table<WoodenFishGalleryCardViewRow> {
|
||||
__sdk::__query_builder::Table::new("wooden_fish_gallery_card_view")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
// 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::wooden_fish_audio_asset_snapshot_type::WoodenFishAudioAssetSnapshot;
|
||||
use super::wooden_fish_image_asset_snapshot_type::WoodenFishImageAssetSnapshot;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
pub struct WoodenFishGalleryViewRow {
|
||||
pub public_work_code: String,
|
||||
pub work_id: String,
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub source_session_id: String,
|
||||
pub author_display_name: String,
|
||||
pub work_title: String,
|
||||
pub work_description: String,
|
||||
pub theme_tags: Vec<String>,
|
||||
pub hit_object_prompt: String,
|
||||
pub hit_object_reference_image_src: Option<String>,
|
||||
pub hit_sound_prompt: Option<String>,
|
||||
pub hit_object_asset: Option<WoodenFishImageAssetSnapshot>,
|
||||
pub hit_sound_asset: Option<WoodenFishAudioAssetSnapshot>,
|
||||
pub floating_words: Vec<String>,
|
||||
pub cover_image_src: String,
|
||||
pub publication_status: String,
|
||||
pub publish_ready: bool,
|
||||
pub play_count: u32,
|
||||
pub generation_status: String,
|
||||
pub updated_at_micros: i64,
|
||||
pub published_at_micros: Option<i64>,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishGalleryViewRow {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
/// Column accessor struct for the table `WoodenFishGalleryViewRow`.
|
||||
///
|
||||
/// Provides typed access to columns for query building.
|
||||
pub struct WoodenFishGalleryViewRowCols {
|
||||
pub public_work_code: __sdk::__query_builder::Col<WoodenFishGalleryViewRow, String>,
|
||||
pub work_id: __sdk::__query_builder::Col<WoodenFishGalleryViewRow, String>,
|
||||
pub profile_id: __sdk::__query_builder::Col<WoodenFishGalleryViewRow, String>,
|
||||
pub owner_user_id: __sdk::__query_builder::Col<WoodenFishGalleryViewRow, String>,
|
||||
pub source_session_id: __sdk::__query_builder::Col<WoodenFishGalleryViewRow, String>,
|
||||
pub author_display_name: __sdk::__query_builder::Col<WoodenFishGalleryViewRow, String>,
|
||||
pub work_title: __sdk::__query_builder::Col<WoodenFishGalleryViewRow, String>,
|
||||
pub work_description: __sdk::__query_builder::Col<WoodenFishGalleryViewRow, String>,
|
||||
pub theme_tags: __sdk::__query_builder::Col<WoodenFishGalleryViewRow, Vec<String>>,
|
||||
pub hit_object_prompt: __sdk::__query_builder::Col<WoodenFishGalleryViewRow, String>,
|
||||
pub hit_object_reference_image_src:
|
||||
__sdk::__query_builder::Col<WoodenFishGalleryViewRow, Option<String>>,
|
||||
pub hit_sound_prompt: __sdk::__query_builder::Col<WoodenFishGalleryViewRow, Option<String>>,
|
||||
pub hit_object_asset:
|
||||
__sdk::__query_builder::Col<WoodenFishGalleryViewRow, Option<WoodenFishImageAssetSnapshot>>,
|
||||
pub hit_sound_asset:
|
||||
__sdk::__query_builder::Col<WoodenFishGalleryViewRow, Option<WoodenFishAudioAssetSnapshot>>,
|
||||
pub floating_words: __sdk::__query_builder::Col<WoodenFishGalleryViewRow, Vec<String>>,
|
||||
pub cover_image_src: __sdk::__query_builder::Col<WoodenFishGalleryViewRow, String>,
|
||||
pub publication_status: __sdk::__query_builder::Col<WoodenFishGalleryViewRow, String>,
|
||||
pub publish_ready: __sdk::__query_builder::Col<WoodenFishGalleryViewRow, bool>,
|
||||
pub play_count: __sdk::__query_builder::Col<WoodenFishGalleryViewRow, u32>,
|
||||
pub generation_status: __sdk::__query_builder::Col<WoodenFishGalleryViewRow, String>,
|
||||
pub updated_at_micros: __sdk::__query_builder::Col<WoodenFishGalleryViewRow, i64>,
|
||||
pub published_at_micros: __sdk::__query_builder::Col<WoodenFishGalleryViewRow, Option<i64>>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasCols for WoodenFishGalleryViewRow {
|
||||
type Cols = WoodenFishGalleryViewRowCols;
|
||||
fn cols(table_name: &'static str) -> Self::Cols {
|
||||
WoodenFishGalleryViewRowCols {
|
||||
public_work_code: __sdk::__query_builder::Col::new(table_name, "public_work_code"),
|
||||
work_id: __sdk::__query_builder::Col::new(table_name, "work_id"),
|
||||
profile_id: __sdk::__query_builder::Col::new(table_name, "profile_id"),
|
||||
owner_user_id: __sdk::__query_builder::Col::new(table_name, "owner_user_id"),
|
||||
source_session_id: __sdk::__query_builder::Col::new(table_name, "source_session_id"),
|
||||
author_display_name: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"author_display_name",
|
||||
),
|
||||
work_title: __sdk::__query_builder::Col::new(table_name, "work_title"),
|
||||
work_description: __sdk::__query_builder::Col::new(table_name, "work_description"),
|
||||
theme_tags: __sdk::__query_builder::Col::new(table_name, "theme_tags"),
|
||||
hit_object_prompt: __sdk::__query_builder::Col::new(table_name, "hit_object_prompt"),
|
||||
hit_object_reference_image_src: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"hit_object_reference_image_src",
|
||||
),
|
||||
hit_sound_prompt: __sdk::__query_builder::Col::new(table_name, "hit_sound_prompt"),
|
||||
hit_object_asset: __sdk::__query_builder::Col::new(table_name, "hit_object_asset"),
|
||||
hit_sound_asset: __sdk::__query_builder::Col::new(table_name, "hit_sound_asset"),
|
||||
floating_words: __sdk::__query_builder::Col::new(table_name, "floating_words"),
|
||||
cover_image_src: __sdk::__query_builder::Col::new(table_name, "cover_image_src"),
|
||||
publication_status: __sdk::__query_builder::Col::new(table_name, "publication_status"),
|
||||
publish_ready: __sdk::__query_builder::Col::new(table_name, "publish_ready"),
|
||||
play_count: __sdk::__query_builder::Col::new(table_name, "play_count"),
|
||||
generation_status: __sdk::__query_builder::Col::new(table_name, "generation_status"),
|
||||
updated_at_micros: __sdk::__query_builder::Col::new(table_name, "updated_at_micros"),
|
||||
published_at_micros: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"published_at_micros",
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
// 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::wooden_fish_audio_asset_snapshot_type::WoodenFishAudioAssetSnapshot;
|
||||
use super::wooden_fish_gallery_view_row_type::WoodenFishGalleryViewRow;
|
||||
use super::wooden_fish_image_asset_snapshot_type::WoodenFishImageAssetSnapshot;
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
/// Table handle for the table `wooden_fish_gallery_view`.
|
||||
///
|
||||
/// Obtain a handle from the [`WoodenFishGalleryViewTableAccess::wooden_fish_gallery_view`] method on [`super::RemoteTables`],
|
||||
/// like `ctx.db.wooden_fish_gallery_view()`.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.wooden_fish_gallery_view().on_insert(...)`.
|
||||
pub struct WoodenFishGalleryViewTableHandle<'ctx> {
|
||||
imp: __sdk::TableHandle<WoodenFishGalleryViewRow>,
|
||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the table `wooden_fish_gallery_view`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteTables`].
|
||||
pub trait WoodenFishGalleryViewTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Obtain a [`WoodenFishGalleryViewTableHandle`], which mediates access to the table `wooden_fish_gallery_view`.
|
||||
fn wooden_fish_gallery_view(&self) -> WoodenFishGalleryViewTableHandle<'_>;
|
||||
}
|
||||
|
||||
impl WoodenFishGalleryViewTableAccess for super::RemoteTables {
|
||||
fn wooden_fish_gallery_view(&self) -> WoodenFishGalleryViewTableHandle<'_> {
|
||||
WoodenFishGalleryViewTableHandle {
|
||||
imp: self
|
||||
.imp
|
||||
.get_table::<WoodenFishGalleryViewRow>("wooden_fish_gallery_view"),
|
||||
ctx: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WoodenFishGalleryViewInsertCallbackId(__sdk::CallbackId);
|
||||
pub struct WoodenFishGalleryViewDeleteCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::Table for WoodenFishGalleryViewTableHandle<'ctx> {
|
||||
type Row = WoodenFishGalleryViewRow;
|
||||
type EventContext = super::EventContext;
|
||||
|
||||
fn count(&self) -> u64 {
|
||||
self.imp.count()
|
||||
}
|
||||
fn iter(&self) -> impl Iterator<Item = WoodenFishGalleryViewRow> + '_ {
|
||||
self.imp.iter()
|
||||
}
|
||||
|
||||
type InsertCallbackId = WoodenFishGalleryViewInsertCallbackId;
|
||||
|
||||
fn on_insert(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> WoodenFishGalleryViewInsertCallbackId {
|
||||
WoodenFishGalleryViewInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_insert(&self, callback: WoodenFishGalleryViewInsertCallbackId) {
|
||||
self.imp.remove_on_insert(callback.0)
|
||||
}
|
||||
|
||||
type DeleteCallbackId = WoodenFishGalleryViewDeleteCallbackId;
|
||||
|
||||
fn on_delete(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> WoodenFishGalleryViewDeleteCallbackId {
|
||||
WoodenFishGalleryViewDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_delete(&self, callback: WoodenFishGalleryViewDeleteCallbackId) {
|
||||
self.imp.remove_on_delete(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
|
||||
let _table =
|
||||
client_cache.get_or_make_table::<WoodenFishGalleryViewRow>("wooden_fish_gallery_view");
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn parse_table_update(
|
||||
raw_updates: __ws::v2::TableUpdate,
|
||||
) -> __sdk::Result<__sdk::TableUpdate<WoodenFishGalleryViewRow>> {
|
||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||
__sdk::InternalError::failed_parse("TableUpdate<WoodenFishGalleryViewRow>", "TableUpdate")
|
||||
.with_cause(e)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for query builder access to the table `WoodenFishGalleryViewRow`.
|
||||
///
|
||||
/// Implemented for [`__sdk::QueryTableAccessor`].
|
||||
pub trait wooden_fish_gallery_viewQueryTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Get a query builder for the table `WoodenFishGalleryViewRow`.
|
||||
fn wooden_fish_gallery_view(&self) -> __sdk::__query_builder::Table<WoodenFishGalleryViewRow>;
|
||||
}
|
||||
|
||||
impl wooden_fish_gallery_viewQueryTableAccess for __sdk::QueryTableAccessor {
|
||||
fn wooden_fish_gallery_view(&self) -> __sdk::__query_builder::Table<WoodenFishGalleryViewRow> {
|
||||
__sdk::__query_builder::Table::new("wooden_fish_gallery_view")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// 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 WoodenFishImageAssetSnapshot {
|
||||
pub asset_id: String,
|
||||
pub image_src: String,
|
||||
pub image_object_key: String,
|
||||
pub asset_object_id: String,
|
||||
pub generation_provider: String,
|
||||
pub prompt: String,
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishImageAssetSnapshot {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// 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 WoodenFishRunCheckpointInput {
|
||||
pub run_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub total_tap_count: u32,
|
||||
pub word_counters_json: String,
|
||||
pub client_event_id: String,
|
||||
pub checkpoint_at_ms: i64,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishRunCheckpointInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// 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 WoodenFishRunFinishInput {
|
||||
pub run_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub total_tap_count: u32,
|
||||
pub word_counters_json: String,
|
||||
pub client_event_id: String,
|
||||
pub finished_at_ms: i64,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishRunFinishInput {
|
||||
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 WoodenFishRunGetInput {
|
||||
pub run_id: String,
|
||||
pub owner_user_id: String,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishRunGetInput {
|
||||
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};
|
||||
|
||||
use super::wooden_fish_run_snapshot_type::WoodenFishRunSnapshot;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
pub struct WoodenFishRunProcedureResult {
|
||||
pub ok: bool,
|
||||
pub run: Option<WoodenFishRunSnapshot>,
|
||||
pub error_message: Option<String>,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishRunProcedureResult {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// 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::wooden_fish_run_status_type::WoodenFishRunStatus;
|
||||
use super::wooden_fish_word_counter_type::WoodenFishWordCounter;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
pub struct WoodenFishRunSnapshot {
|
||||
pub run_id: String,
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub status: WoodenFishRunStatus,
|
||||
pub total_tap_count: u32,
|
||||
pub word_counters: Vec<WoodenFishWordCounter>,
|
||||
pub started_at_ms: u64,
|
||||
pub updated_at_ms: u64,
|
||||
pub finished_at_ms: Option<u64>,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishRunSnapshot {
|
||||
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 WoodenFishRunStartInput {
|
||||
pub run_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub profile_id: String,
|
||||
pub client_event_id: String,
|
||||
pub started_at_ms: i64,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishRunStartInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// 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)]
|
||||
#[derive(Copy, Eq, Hash)]
|
||||
pub enum WoodenFishRunStatus {
|
||||
Playing,
|
||||
|
||||
Finished,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishRunStatus {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
// 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 WoodenFishRuntimeRunRow {
|
||||
pub run_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub profile_id: String,
|
||||
pub status: String,
|
||||
pub total_tap_count: u32,
|
||||
pub word_counters_json: String,
|
||||
pub started_at_ms: i64,
|
||||
pub updated_at_ms: i64,
|
||||
pub finished_at_ms: i64,
|
||||
pub snapshot_json: String,
|
||||
pub created_at: __sdk::Timestamp,
|
||||
pub updated_at: __sdk::Timestamp,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishRuntimeRunRow {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
/// Column accessor struct for the table `WoodenFishRuntimeRunRow`.
|
||||
///
|
||||
/// Provides typed access to columns for query building.
|
||||
pub struct WoodenFishRuntimeRunRowCols {
|
||||
pub run_id: __sdk::__query_builder::Col<WoodenFishRuntimeRunRow, String>,
|
||||
pub owner_user_id: __sdk::__query_builder::Col<WoodenFishRuntimeRunRow, String>,
|
||||
pub profile_id: __sdk::__query_builder::Col<WoodenFishRuntimeRunRow, String>,
|
||||
pub status: __sdk::__query_builder::Col<WoodenFishRuntimeRunRow, String>,
|
||||
pub total_tap_count: __sdk::__query_builder::Col<WoodenFishRuntimeRunRow, u32>,
|
||||
pub word_counters_json: __sdk::__query_builder::Col<WoodenFishRuntimeRunRow, String>,
|
||||
pub started_at_ms: __sdk::__query_builder::Col<WoodenFishRuntimeRunRow, i64>,
|
||||
pub updated_at_ms: __sdk::__query_builder::Col<WoodenFishRuntimeRunRow, i64>,
|
||||
pub finished_at_ms: __sdk::__query_builder::Col<WoodenFishRuntimeRunRow, i64>,
|
||||
pub snapshot_json: __sdk::__query_builder::Col<WoodenFishRuntimeRunRow, String>,
|
||||
pub created_at: __sdk::__query_builder::Col<WoodenFishRuntimeRunRow, __sdk::Timestamp>,
|
||||
pub updated_at: __sdk::__query_builder::Col<WoodenFishRuntimeRunRow, __sdk::Timestamp>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasCols for WoodenFishRuntimeRunRow {
|
||||
type Cols = WoodenFishRuntimeRunRowCols;
|
||||
fn cols(table_name: &'static str) -> Self::Cols {
|
||||
WoodenFishRuntimeRunRowCols {
|
||||
run_id: __sdk::__query_builder::Col::new(table_name, "run_id"),
|
||||
owner_user_id: __sdk::__query_builder::Col::new(table_name, "owner_user_id"),
|
||||
profile_id: __sdk::__query_builder::Col::new(table_name, "profile_id"),
|
||||
status: __sdk::__query_builder::Col::new(table_name, "status"),
|
||||
total_tap_count: __sdk::__query_builder::Col::new(table_name, "total_tap_count"),
|
||||
word_counters_json: __sdk::__query_builder::Col::new(table_name, "word_counters_json"),
|
||||
started_at_ms: __sdk::__query_builder::Col::new(table_name, "started_at_ms"),
|
||||
updated_at_ms: __sdk::__query_builder::Col::new(table_name, "updated_at_ms"),
|
||||
finished_at_ms: __sdk::__query_builder::Col::new(table_name, "finished_at_ms"),
|
||||
snapshot_json: __sdk::__query_builder::Col::new(table_name, "snapshot_json"),
|
||||
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 `WoodenFishRuntimeRunRow`.
|
||||
///
|
||||
/// Provides typed access to indexed columns for query building.
|
||||
pub struct WoodenFishRuntimeRunRowIxCols {
|
||||
pub owner_user_id: __sdk::__query_builder::IxCol<WoodenFishRuntimeRunRow, String>,
|
||||
pub profile_id: __sdk::__query_builder::IxCol<WoodenFishRuntimeRunRow, String>,
|
||||
pub run_id: __sdk::__query_builder::IxCol<WoodenFishRuntimeRunRow, String>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasIxCols for WoodenFishRuntimeRunRow {
|
||||
type IxCols = WoodenFishRuntimeRunRowIxCols;
|
||||
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
||||
WoodenFishRuntimeRunRowIxCols {
|
||||
owner_user_id: __sdk::__query_builder::IxCol::new(table_name, "owner_user_id"),
|
||||
profile_id: __sdk::__query_builder::IxCol::new(table_name, "profile_id"),
|
||||
run_id: __sdk::__query_builder::IxCol::new(table_name, "run_id"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::CanBeLookupTable for WoodenFishRuntimeRunRow {}
|
||||
@@ -0,0 +1,162 @@
|
||||
// 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::wooden_fish_runtime_run_row_type::WoodenFishRuntimeRunRow;
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
/// Table handle for the table `wooden_fish_runtime_run`.
|
||||
///
|
||||
/// Obtain a handle from the [`WoodenFishRuntimeRunTableAccess::wooden_fish_runtime_run`] method on [`super::RemoteTables`],
|
||||
/// like `ctx.db.wooden_fish_runtime_run()`.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.wooden_fish_runtime_run().on_insert(...)`.
|
||||
pub struct WoodenFishRuntimeRunTableHandle<'ctx> {
|
||||
imp: __sdk::TableHandle<WoodenFishRuntimeRunRow>,
|
||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the table `wooden_fish_runtime_run`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteTables`].
|
||||
pub trait WoodenFishRuntimeRunTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Obtain a [`WoodenFishRuntimeRunTableHandle`], which mediates access to the table `wooden_fish_runtime_run`.
|
||||
fn wooden_fish_runtime_run(&self) -> WoodenFishRuntimeRunTableHandle<'_>;
|
||||
}
|
||||
|
||||
impl WoodenFishRuntimeRunTableAccess for super::RemoteTables {
|
||||
fn wooden_fish_runtime_run(&self) -> WoodenFishRuntimeRunTableHandle<'_> {
|
||||
WoodenFishRuntimeRunTableHandle {
|
||||
imp: self
|
||||
.imp
|
||||
.get_table::<WoodenFishRuntimeRunRow>("wooden_fish_runtime_run"),
|
||||
ctx: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WoodenFishRuntimeRunInsertCallbackId(__sdk::CallbackId);
|
||||
pub struct WoodenFishRuntimeRunDeleteCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::Table for WoodenFishRuntimeRunTableHandle<'ctx> {
|
||||
type Row = WoodenFishRuntimeRunRow;
|
||||
type EventContext = super::EventContext;
|
||||
|
||||
fn count(&self) -> u64 {
|
||||
self.imp.count()
|
||||
}
|
||||
fn iter(&self) -> impl Iterator<Item = WoodenFishRuntimeRunRow> + '_ {
|
||||
self.imp.iter()
|
||||
}
|
||||
|
||||
type InsertCallbackId = WoodenFishRuntimeRunInsertCallbackId;
|
||||
|
||||
fn on_insert(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> WoodenFishRuntimeRunInsertCallbackId {
|
||||
WoodenFishRuntimeRunInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_insert(&self, callback: WoodenFishRuntimeRunInsertCallbackId) {
|
||||
self.imp.remove_on_insert(callback.0)
|
||||
}
|
||||
|
||||
type DeleteCallbackId = WoodenFishRuntimeRunDeleteCallbackId;
|
||||
|
||||
fn on_delete(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> WoodenFishRuntimeRunDeleteCallbackId {
|
||||
WoodenFishRuntimeRunDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_delete(&self, callback: WoodenFishRuntimeRunDeleteCallbackId) {
|
||||
self.imp.remove_on_delete(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WoodenFishRuntimeRunUpdateCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::TableWithPrimaryKey for WoodenFishRuntimeRunTableHandle<'ctx> {
|
||||
type UpdateCallbackId = WoodenFishRuntimeRunUpdateCallbackId;
|
||||
|
||||
fn on_update(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||
) -> WoodenFishRuntimeRunUpdateCallbackId {
|
||||
WoodenFishRuntimeRunUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_update(&self, callback: WoodenFishRuntimeRunUpdateCallbackId) {
|
||||
self.imp.remove_on_update(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Access to the `run_id` unique index on the table `wooden_fish_runtime_run`,
|
||||
/// which allows point queries on the field of the same name
|
||||
/// via the [`WoodenFishRuntimeRunRunIdUnique::find`] method.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.wooden_fish_runtime_run().run_id().find(...)`.
|
||||
pub struct WoodenFishRuntimeRunRunIdUnique<'ctx> {
|
||||
imp: __sdk::UniqueConstraintHandle<WoodenFishRuntimeRunRow, String>,
|
||||
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
impl<'ctx> WoodenFishRuntimeRunTableHandle<'ctx> {
|
||||
/// Get a handle on the `run_id` unique index on the table `wooden_fish_runtime_run`.
|
||||
pub fn run_id(&self) -> WoodenFishRuntimeRunRunIdUnique<'ctx> {
|
||||
WoodenFishRuntimeRunRunIdUnique {
|
||||
imp: self.imp.get_unique_constraint::<String>("run_id"),
|
||||
phantom: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> WoodenFishRuntimeRunRunIdUnique<'ctx> {
|
||||
/// Find the subscribed row whose `run_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<WoodenFishRuntimeRunRow> {
|
||||
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::<WoodenFishRuntimeRunRow>("wooden_fish_runtime_run");
|
||||
_table.add_unique_constraint::<String>("run_id", |row| &row.run_id);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn parse_table_update(
|
||||
raw_updates: __ws::v2::TableUpdate,
|
||||
) -> __sdk::Result<__sdk::TableUpdate<WoodenFishRuntimeRunRow>> {
|
||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||
__sdk::InternalError::failed_parse("TableUpdate<WoodenFishRuntimeRunRow>", "TableUpdate")
|
||||
.with_cause(e)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for query builder access to the table `WoodenFishRuntimeRunRow`.
|
||||
///
|
||||
/// Implemented for [`__sdk::QueryTableAccessor`].
|
||||
pub trait wooden_fish_runtime_runQueryTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Get a query builder for the table `WoodenFishRuntimeRunRow`.
|
||||
fn wooden_fish_runtime_run(&self) -> __sdk::__query_builder::Table<WoodenFishRuntimeRunRow>;
|
||||
}
|
||||
|
||||
impl wooden_fish_runtime_runQueryTableAccess for __sdk::QueryTableAccessor {
|
||||
fn wooden_fish_runtime_run(&self) -> __sdk::__query_builder::Table<WoodenFishRuntimeRunRow> {
|
||||
__sdk::__query_builder::Table::new("wooden_fish_runtime_run")
|
||||
}
|
||||
}
|
||||
@@ -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 WoodenFishWordCounter {
|
||||
pub text: String,
|
||||
pub count: u32,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishWordCounter {
|
||||
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 WoodenFishWorkGetInput {
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishWorkGetInput {
|
||||
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};
|
||||
|
||||
use super::wooden_fish_work_snapshot_type::WoodenFishWorkSnapshot;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
pub struct WoodenFishWorkProcedureResult {
|
||||
pub ok: bool,
|
||||
pub work: Option<WoodenFishWorkSnapshot>,
|
||||
pub error_message: Option<String>,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishWorkProcedureResult {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
// 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 WoodenFishWorkProfileRow {
|
||||
pub profile_id: String,
|
||||
pub work_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub source_session_id: String,
|
||||
pub author_display_name: String,
|
||||
pub work_title: String,
|
||||
pub work_description: String,
|
||||
pub theme_tags_json: String,
|
||||
pub hit_object_prompt: String,
|
||||
pub hit_object_reference_image_src: String,
|
||||
pub hit_sound_prompt: String,
|
||||
pub hit_object_asset_json: String,
|
||||
pub hit_sound_asset_json: String,
|
||||
pub floating_words_json: String,
|
||||
pub cover_image_src: String,
|
||||
pub generation_status: String,
|
||||
pub publication_status: String,
|
||||
pub play_count: u32,
|
||||
pub updated_at: __sdk::Timestamp,
|
||||
pub published_at: Option<__sdk::Timestamp>,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishWorkProfileRow {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
|
||||
/// Column accessor struct for the table `WoodenFishWorkProfileRow`.
|
||||
///
|
||||
/// Provides typed access to columns for query building.
|
||||
pub struct WoodenFishWorkProfileRowCols {
|
||||
pub profile_id: __sdk::__query_builder::Col<WoodenFishWorkProfileRow, String>,
|
||||
pub work_id: __sdk::__query_builder::Col<WoodenFishWorkProfileRow, String>,
|
||||
pub owner_user_id: __sdk::__query_builder::Col<WoodenFishWorkProfileRow, String>,
|
||||
pub source_session_id: __sdk::__query_builder::Col<WoodenFishWorkProfileRow, String>,
|
||||
pub author_display_name: __sdk::__query_builder::Col<WoodenFishWorkProfileRow, String>,
|
||||
pub work_title: __sdk::__query_builder::Col<WoodenFishWorkProfileRow, String>,
|
||||
pub work_description: __sdk::__query_builder::Col<WoodenFishWorkProfileRow, String>,
|
||||
pub theme_tags_json: __sdk::__query_builder::Col<WoodenFishWorkProfileRow, String>,
|
||||
pub hit_object_prompt: __sdk::__query_builder::Col<WoodenFishWorkProfileRow, String>,
|
||||
pub hit_object_reference_image_src:
|
||||
__sdk::__query_builder::Col<WoodenFishWorkProfileRow, String>,
|
||||
pub hit_sound_prompt: __sdk::__query_builder::Col<WoodenFishWorkProfileRow, String>,
|
||||
pub hit_object_asset_json: __sdk::__query_builder::Col<WoodenFishWorkProfileRow, String>,
|
||||
pub hit_sound_asset_json: __sdk::__query_builder::Col<WoodenFishWorkProfileRow, String>,
|
||||
pub floating_words_json: __sdk::__query_builder::Col<WoodenFishWorkProfileRow, String>,
|
||||
pub cover_image_src: __sdk::__query_builder::Col<WoodenFishWorkProfileRow, String>,
|
||||
pub generation_status: __sdk::__query_builder::Col<WoodenFishWorkProfileRow, String>,
|
||||
pub publication_status: __sdk::__query_builder::Col<WoodenFishWorkProfileRow, String>,
|
||||
pub play_count: __sdk::__query_builder::Col<WoodenFishWorkProfileRow, u32>,
|
||||
pub updated_at: __sdk::__query_builder::Col<WoodenFishWorkProfileRow, __sdk::Timestamp>,
|
||||
pub published_at:
|
||||
__sdk::__query_builder::Col<WoodenFishWorkProfileRow, Option<__sdk::Timestamp>>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasCols for WoodenFishWorkProfileRow {
|
||||
type Cols = WoodenFishWorkProfileRowCols;
|
||||
fn cols(table_name: &'static str) -> Self::Cols {
|
||||
WoodenFishWorkProfileRowCols {
|
||||
profile_id: __sdk::__query_builder::Col::new(table_name, "profile_id"),
|
||||
work_id: __sdk::__query_builder::Col::new(table_name, "work_id"),
|
||||
owner_user_id: __sdk::__query_builder::Col::new(table_name, "owner_user_id"),
|
||||
source_session_id: __sdk::__query_builder::Col::new(table_name, "source_session_id"),
|
||||
author_display_name: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"author_display_name",
|
||||
),
|
||||
work_title: __sdk::__query_builder::Col::new(table_name, "work_title"),
|
||||
work_description: __sdk::__query_builder::Col::new(table_name, "work_description"),
|
||||
theme_tags_json: __sdk::__query_builder::Col::new(table_name, "theme_tags_json"),
|
||||
hit_object_prompt: __sdk::__query_builder::Col::new(table_name, "hit_object_prompt"),
|
||||
hit_object_reference_image_src: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"hit_object_reference_image_src",
|
||||
),
|
||||
hit_sound_prompt: __sdk::__query_builder::Col::new(table_name, "hit_sound_prompt"),
|
||||
hit_object_asset_json: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"hit_object_asset_json",
|
||||
),
|
||||
hit_sound_asset_json: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"hit_sound_asset_json",
|
||||
),
|
||||
floating_words_json: __sdk::__query_builder::Col::new(
|
||||
table_name,
|
||||
"floating_words_json",
|
||||
),
|
||||
cover_image_src: __sdk::__query_builder::Col::new(table_name, "cover_image_src"),
|
||||
generation_status: __sdk::__query_builder::Col::new(table_name, "generation_status"),
|
||||
publication_status: __sdk::__query_builder::Col::new(table_name, "publication_status"),
|
||||
play_count: __sdk::__query_builder::Col::new(table_name, "play_count"),
|
||||
updated_at: __sdk::__query_builder::Col::new(table_name, "updated_at"),
|
||||
published_at: __sdk::__query_builder::Col::new(table_name, "published_at"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Indexed column accessor struct for the table `WoodenFishWorkProfileRow`.
|
||||
///
|
||||
/// Provides typed access to indexed columns for query building.
|
||||
pub struct WoodenFishWorkProfileRowIxCols {
|
||||
pub owner_user_id: __sdk::__query_builder::IxCol<WoodenFishWorkProfileRow, String>,
|
||||
pub profile_id: __sdk::__query_builder::IxCol<WoodenFishWorkProfileRow, String>,
|
||||
pub publication_status: __sdk::__query_builder::IxCol<WoodenFishWorkProfileRow, String>,
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::HasIxCols for WoodenFishWorkProfileRow {
|
||||
type IxCols = WoodenFishWorkProfileRowIxCols;
|
||||
fn ix_cols(table_name: &'static str) -> Self::IxCols {
|
||||
WoodenFishWorkProfileRowIxCols {
|
||||
owner_user_id: __sdk::__query_builder::IxCol::new(table_name, "owner_user_id"),
|
||||
profile_id: __sdk::__query_builder::IxCol::new(table_name, "profile_id"),
|
||||
publication_status: __sdk::__query_builder::IxCol::new(
|
||||
table_name,
|
||||
"publication_status",
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl __sdk::__query_builder::CanBeLookupTable for WoodenFishWorkProfileRow {}
|
||||
@@ -0,0 +1,162 @@
|
||||
// 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::wooden_fish_work_profile_row_type::WoodenFishWorkProfileRow;
|
||||
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
|
||||
|
||||
/// Table handle for the table `wooden_fish_work_profile`.
|
||||
///
|
||||
/// Obtain a handle from the [`WoodenFishWorkProfileTableAccess::wooden_fish_work_profile`] method on [`super::RemoteTables`],
|
||||
/// like `ctx.db.wooden_fish_work_profile()`.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.wooden_fish_work_profile().on_insert(...)`.
|
||||
pub struct WoodenFishWorkProfileTableHandle<'ctx> {
|
||||
imp: __sdk::TableHandle<WoodenFishWorkProfileRow>,
|
||||
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for access to the table `wooden_fish_work_profile`.
|
||||
///
|
||||
/// Implemented for [`super::RemoteTables`].
|
||||
pub trait WoodenFishWorkProfileTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Obtain a [`WoodenFishWorkProfileTableHandle`], which mediates access to the table `wooden_fish_work_profile`.
|
||||
fn wooden_fish_work_profile(&self) -> WoodenFishWorkProfileTableHandle<'_>;
|
||||
}
|
||||
|
||||
impl WoodenFishWorkProfileTableAccess for super::RemoteTables {
|
||||
fn wooden_fish_work_profile(&self) -> WoodenFishWorkProfileTableHandle<'_> {
|
||||
WoodenFishWorkProfileTableHandle {
|
||||
imp: self
|
||||
.imp
|
||||
.get_table::<WoodenFishWorkProfileRow>("wooden_fish_work_profile"),
|
||||
ctx: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WoodenFishWorkProfileInsertCallbackId(__sdk::CallbackId);
|
||||
pub struct WoodenFishWorkProfileDeleteCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::Table for WoodenFishWorkProfileTableHandle<'ctx> {
|
||||
type Row = WoodenFishWorkProfileRow;
|
||||
type EventContext = super::EventContext;
|
||||
|
||||
fn count(&self) -> u64 {
|
||||
self.imp.count()
|
||||
}
|
||||
fn iter(&self) -> impl Iterator<Item = WoodenFishWorkProfileRow> + '_ {
|
||||
self.imp.iter()
|
||||
}
|
||||
|
||||
type InsertCallbackId = WoodenFishWorkProfileInsertCallbackId;
|
||||
|
||||
fn on_insert(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> WoodenFishWorkProfileInsertCallbackId {
|
||||
WoodenFishWorkProfileInsertCallbackId(self.imp.on_insert(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_insert(&self, callback: WoodenFishWorkProfileInsertCallbackId) {
|
||||
self.imp.remove_on_insert(callback.0)
|
||||
}
|
||||
|
||||
type DeleteCallbackId = WoodenFishWorkProfileDeleteCallbackId;
|
||||
|
||||
fn on_delete(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row) + Send + 'static,
|
||||
) -> WoodenFishWorkProfileDeleteCallbackId {
|
||||
WoodenFishWorkProfileDeleteCallbackId(self.imp.on_delete(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_delete(&self, callback: WoodenFishWorkProfileDeleteCallbackId) {
|
||||
self.imp.remove_on_delete(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WoodenFishWorkProfileUpdateCallbackId(__sdk::CallbackId);
|
||||
|
||||
impl<'ctx> __sdk::TableWithPrimaryKey for WoodenFishWorkProfileTableHandle<'ctx> {
|
||||
type UpdateCallbackId = WoodenFishWorkProfileUpdateCallbackId;
|
||||
|
||||
fn on_update(
|
||||
&self,
|
||||
callback: impl FnMut(&Self::EventContext, &Self::Row, &Self::Row) + Send + 'static,
|
||||
) -> WoodenFishWorkProfileUpdateCallbackId {
|
||||
WoodenFishWorkProfileUpdateCallbackId(self.imp.on_update(Box::new(callback)))
|
||||
}
|
||||
|
||||
fn remove_on_update(&self, callback: WoodenFishWorkProfileUpdateCallbackId) {
|
||||
self.imp.remove_on_update(callback.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Access to the `profile_id` unique index on the table `wooden_fish_work_profile`,
|
||||
/// which allows point queries on the field of the same name
|
||||
/// via the [`WoodenFishWorkProfileProfileIdUnique::find`] method.
|
||||
///
|
||||
/// Users are encouraged not to explicitly reference this type,
|
||||
/// but to directly chain method calls,
|
||||
/// like `ctx.db.wooden_fish_work_profile().profile_id().find(...)`.
|
||||
pub struct WoodenFishWorkProfileProfileIdUnique<'ctx> {
|
||||
imp: __sdk::UniqueConstraintHandle<WoodenFishWorkProfileRow, String>,
|
||||
phantom: std::marker::PhantomData<&'ctx super::RemoteTables>,
|
||||
}
|
||||
|
||||
impl<'ctx> WoodenFishWorkProfileTableHandle<'ctx> {
|
||||
/// Get a handle on the `profile_id` unique index on the table `wooden_fish_work_profile`.
|
||||
pub fn profile_id(&self) -> WoodenFishWorkProfileProfileIdUnique<'ctx> {
|
||||
WoodenFishWorkProfileProfileIdUnique {
|
||||
imp: self.imp.get_unique_constraint::<String>("profile_id"),
|
||||
phantom: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> WoodenFishWorkProfileProfileIdUnique<'ctx> {
|
||||
/// Find the subscribed row whose `profile_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<WoodenFishWorkProfileRow> {
|
||||
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::<WoodenFishWorkProfileRow>("wooden_fish_work_profile");
|
||||
_table.add_unique_constraint::<String>("profile_id", |row| &row.profile_id);
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub(super) fn parse_table_update(
|
||||
raw_updates: __ws::v2::TableUpdate,
|
||||
) -> __sdk::Result<__sdk::TableUpdate<WoodenFishWorkProfileRow>> {
|
||||
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
|
||||
__sdk::InternalError::failed_parse("TableUpdate<WoodenFishWorkProfileRow>", "TableUpdate")
|
||||
.with_cause(e)
|
||||
.into()
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
/// Extension trait for query builder access to the table `WoodenFishWorkProfileRow`.
|
||||
///
|
||||
/// Implemented for [`__sdk::QueryTableAccessor`].
|
||||
pub trait wooden_fish_work_profileQueryTableAccess {
|
||||
#[allow(non_snake_case)]
|
||||
/// Get a query builder for the table `WoodenFishWorkProfileRow`.
|
||||
fn wooden_fish_work_profile(&self) -> __sdk::__query_builder::Table<WoodenFishWorkProfileRow>;
|
||||
}
|
||||
|
||||
impl wooden_fish_work_profileQueryTableAccess for __sdk::QueryTableAccessor {
|
||||
fn wooden_fish_work_profile(&self) -> __sdk::__query_builder::Table<WoodenFishWorkProfileRow> {
|
||||
__sdk::__query_builder::Table::new("wooden_fish_work_profile")
|
||||
}
|
||||
}
|
||||
@@ -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 WoodenFishWorkPublishInput {
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub published_at_micros: i64,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishWorkPublishInput {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// 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::wooden_fish_audio_asset_snapshot_type::WoodenFishAudioAssetSnapshot;
|
||||
use super::wooden_fish_image_asset_snapshot_type::WoodenFishImageAssetSnapshot;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
pub struct WoodenFishWorkSnapshot {
|
||||
pub work_id: String,
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub source_session_id: String,
|
||||
pub author_display_name: String,
|
||||
pub work_title: String,
|
||||
pub work_description: String,
|
||||
pub theme_tags: Vec<String>,
|
||||
pub hit_object_prompt: String,
|
||||
pub hit_object_reference_image_src: Option<String>,
|
||||
pub hit_sound_prompt: Option<String>,
|
||||
pub hit_object_asset: Option<WoodenFishImageAssetSnapshot>,
|
||||
pub hit_sound_asset: Option<WoodenFishAudioAssetSnapshot>,
|
||||
pub floating_words: Vec<String>,
|
||||
pub cover_image_src: String,
|
||||
pub publication_status: String,
|
||||
pub publish_ready: bool,
|
||||
pub play_count: u32,
|
||||
pub generation_status: String,
|
||||
pub updated_at_micros: i64,
|
||||
pub published_at_micros: Option<i64>,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishWorkSnapshot {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// 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 WoodenFishWorkUpdateInput {
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub work_title: String,
|
||||
pub work_description: String,
|
||||
pub theme_tags_json: String,
|
||||
pub hit_object_prompt: Option<String>,
|
||||
pub hit_object_reference_image_src: Option<String>,
|
||||
pub hit_sound_prompt: Option<String>,
|
||||
pub hit_object_asset_json: Option<String>,
|
||||
pub hit_sound_asset_json: Option<String>,
|
||||
pub floating_words_json: Option<String>,
|
||||
pub cover_image_src: Option<String>,
|
||||
pub generation_status: Option<String>,
|
||||
pub updated_at_micros: i64,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishWorkUpdateInput {
|
||||
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 WoodenFishWorksListInput {
|
||||
pub owner_user_id: String,
|
||||
pub published_only: bool,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishWorksListInput {
|
||||
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};
|
||||
|
||||
use super::wooden_fish_work_snapshot_type::WoodenFishWorkSnapshot;
|
||||
|
||||
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
|
||||
#[sats(crate = __lib)]
|
||||
pub struct WoodenFishWorksProcedureResult {
|
||||
pub ok: bool,
|
||||
pub items: Vec<WoodenFishWorkSnapshot>,
|
||||
pub error_message: Option<String>,
|
||||
}
|
||||
|
||||
impl __sdk::InModule for WoodenFishWorksProcedureResult {
|
||||
type Module = super::RemoteModule;
|
||||
}
|
||||
@@ -81,7 +81,9 @@ fn spacetime_metrics() -> &'static SpacetimeMetrics {
|
||||
read_duration_ms: meter
|
||||
.f64_histogram("genarrative.spacetime.read.duration_ms")
|
||||
.with_unit("ms")
|
||||
.with_description("SpacetimeDB local subscription cache read duration in milliseconds")
|
||||
.with_description(
|
||||
"SpacetimeDB local subscription cache read duration in milliseconds",
|
||||
)
|
||||
.build(),
|
||||
}
|
||||
})
|
||||
|
||||
1031
server-rs/crates/spacetime-client/src/wooden_fish.rs
Normal file
1031
server-rs/crates/spacetime-client/src/wooden_fish.rs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -19,6 +19,7 @@ module-combat = { workspace = true, features = ["spacetime-types"] }
|
||||
module-inventory = { workspace = true, features = ["spacetime-types"] }
|
||||
module-custom-world = { workspace = true, features = ["spacetime-types"] }
|
||||
module-jump-hop = { workspace = true, features = ["spacetime-types"] }
|
||||
module-wooden-fish = { workspace = true, features = ["spacetime-types"] }
|
||||
module-match3d = { workspace = true }
|
||||
module-npc = { workspace = true, features = ["spacetime-types"] }
|
||||
module-puzzle = { workspace = true, features = ["spacetime-types"] }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// 中文注释:SpacetimeDB 绑定生成依赖根模块继续公开 re-export 各领域类型;
|
||||
// 中文注释:SpacetimeDB 绑定生成依赖根模块继续公开 re-export 各领域类型;
|
||||
// 少数领域 helper 同名只影响 value namespace 导出,不影响 table / reducer 类型。
|
||||
#![allow(ambiguous_glob_reexports)]
|
||||
|
||||
@@ -15,6 +15,7 @@ pub use module_quest::*;
|
||||
pub use module_runtime::*;
|
||||
pub use module_runtime_item::*;
|
||||
pub use module_story::*;
|
||||
pub use module_wooden_fish::*;
|
||||
|
||||
pub(crate) use serde_json::{Map as JsonMap, Value as JsonValue, json};
|
||||
pub(crate) use shared_kernel::format_timestamp_micros;
|
||||
@@ -37,6 +38,7 @@ mod puzzle;
|
||||
mod runtime;
|
||||
mod square_hole;
|
||||
mod visual_novel;
|
||||
mod wooden_fish;
|
||||
|
||||
pub use ai::*;
|
||||
pub use asset_metadata::*;
|
||||
@@ -53,3 +55,4 @@ pub use migration::*;
|
||||
pub use runtime::*;
|
||||
pub use square_hole::*;
|
||||
pub use visual_novel::*;
|
||||
pub use wooden_fish::*;
|
||||
|
||||
@@ -26,6 +26,9 @@ use crate::square_hole::tables::{
|
||||
square_hole_agent_message, square_hole_agent_session, square_hole_runtime_run,
|
||||
square_hole_work_profile,
|
||||
};
|
||||
use crate::wooden_fish::tables::{
|
||||
wooden_fish_agent_session, wooden_fish_event, wooden_fish_runtime_run, wooden_fish_work_profile,
|
||||
};
|
||||
use crate::{
|
||||
visual_novel_agent_message, visual_novel_agent_session, visual_novel_runtime_event,
|
||||
visual_novel_runtime_history_entry, visual_novel_runtime_run, visual_novel_work_profile,
|
||||
@@ -241,6 +244,10 @@ macro_rules! migration_tables {
|
||||
jump_hop_work_profile,
|
||||
jump_hop_runtime_run,
|
||||
jump_hop_event,
|
||||
wooden_fish_agent_session,
|
||||
wooden_fish_work_profile,
|
||||
wooden_fish_runtime_run,
|
||||
wooden_fish_event,
|
||||
square_hole_agent_session,
|
||||
square_hole_agent_message,
|
||||
square_hole_work_profile,
|
||||
|
||||
@@ -192,6 +192,7 @@ fn seed_creation_entry_config_if_missing(ctx: &ReducerContext) {
|
||||
},
|
||||
);
|
||||
migrate_baby_object_match_entry_from_old_coming_soon_default(ctx, now);
|
||||
migrate_wooden_fish_entry_from_old_puzzle_image_default(ctx, now);
|
||||
}
|
||||
|
||||
fn migrate_visual_novel_entry_from_old_visible_default(ctx: &ReducerContext, now: Timestamp) {
|
||||
@@ -296,6 +297,34 @@ fn migrate_baby_object_match_entry_from_old_coming_soon_default(
|
||||
});
|
||||
}
|
||||
|
||||
fn migrate_wooden_fish_entry_from_old_puzzle_image_default(ctx: &ReducerContext, now: Timestamp) {
|
||||
let id = "wooden-fish".to_string();
|
||||
let Some(row) = ctx.db.creation_entry_type_config().id().find(&id) else {
|
||||
return;
|
||||
};
|
||||
|
||||
// 中文注释:只替换敲木鱼旧默认入口图,不覆盖后台手动设置过的其它展示信息。
|
||||
let still_old_puzzle_image_default = row.title == "敲木鱼"
|
||||
&& row.subtitle == "点击祈福轻玩法"
|
||||
&& row.badge == "可创建"
|
||||
&& row.image_src == "/creation-type-references/puzzle.webp"
|
||||
&& row.visible
|
||||
&& row.open
|
||||
&& row.sort_order == 47;
|
||||
if !still_old_puzzle_image_default {
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.db
|
||||
.creation_entry_type_config()
|
||||
.id()
|
||||
.update(CreationEntryTypeConfig {
|
||||
image_src: "/wooden-fish/default-hit-object.png".to_string(),
|
||||
updated_at: now,
|
||||
..row
|
||||
});
|
||||
}
|
||||
|
||||
fn default_creation_entry_type_configs(now: Timestamp) -> Vec<CreationEntryTypeConfig> {
|
||||
module_runtime::default_creation_entry_type_snapshots(now.to_micros_since_unix_epoch())
|
||||
.into_iter()
|
||||
|
||||
1228
server-rs/crates/spacetime-module/src/wooden_fish.rs
Normal file
1228
server-rs/crates/spacetime-module/src/wooden_fish.rs
Normal file
File diff suppressed because it is too large
Load Diff
85
server-rs/crates/spacetime-module/src/wooden_fish/tables.rs
Normal file
85
server-rs/crates/spacetime-module/src/wooden_fish/tables.rs
Normal file
@@ -0,0 +1,85 @@
|
||||
use crate::*;
|
||||
|
||||
#[spacetimedb::table(
|
||||
accessor = wooden_fish_agent_session,
|
||||
index(accessor = by_wooden_fish_agent_session_owner_user_id, btree(columns = [owner_user_id]))
|
||||
)]
|
||||
pub struct WoodenFishAgentSessionRow {
|
||||
#[primary_key]
|
||||
pub(crate) session_id: String,
|
||||
pub(crate) owner_user_id: String,
|
||||
pub(crate) current_turn: u32,
|
||||
pub(crate) progress_percent: u32,
|
||||
pub(crate) stage: String,
|
||||
pub(crate) config_json: String,
|
||||
pub(crate) draft_json: String,
|
||||
pub(crate) published_profile_id: String,
|
||||
pub(crate) created_at: Timestamp,
|
||||
pub(crate) updated_at: Timestamp,
|
||||
}
|
||||
|
||||
#[spacetimedb::table(
|
||||
accessor = wooden_fish_work_profile,
|
||||
index(accessor = by_wooden_fish_work_owner_user_id, btree(columns = [owner_user_id])),
|
||||
index(accessor = by_wooden_fish_work_publication_status, btree(columns = [publication_status]))
|
||||
)]
|
||||
pub struct WoodenFishWorkProfileRow {
|
||||
#[primary_key]
|
||||
pub(crate) profile_id: String,
|
||||
pub(crate) work_id: String,
|
||||
pub(crate) owner_user_id: String,
|
||||
pub(crate) source_session_id: String,
|
||||
pub(crate) author_display_name: String,
|
||||
pub(crate) work_title: String,
|
||||
pub(crate) work_description: String,
|
||||
pub(crate) theme_tags_json: String,
|
||||
pub(crate) hit_object_prompt: String,
|
||||
pub(crate) hit_object_reference_image_src: String,
|
||||
pub(crate) hit_sound_prompt: String,
|
||||
pub(crate) hit_object_asset_json: String,
|
||||
pub(crate) hit_sound_asset_json: String,
|
||||
pub(crate) floating_words_json: String,
|
||||
pub(crate) cover_image_src: String,
|
||||
pub(crate) generation_status: String,
|
||||
pub(crate) publication_status: String,
|
||||
pub(crate) play_count: u32,
|
||||
pub(crate) updated_at: Timestamp,
|
||||
pub(crate) published_at: Option<Timestamp>,
|
||||
}
|
||||
|
||||
#[spacetimedb::table(
|
||||
accessor = wooden_fish_runtime_run,
|
||||
index(accessor = by_wooden_fish_run_owner_user_id, btree(columns = [owner_user_id])),
|
||||
index(accessor = by_wooden_fish_run_profile_id, btree(columns = [profile_id]))
|
||||
)]
|
||||
pub struct WoodenFishRuntimeRunRow {
|
||||
#[primary_key]
|
||||
pub(crate) run_id: String,
|
||||
pub(crate) owner_user_id: String,
|
||||
pub(crate) profile_id: String,
|
||||
pub(crate) status: String,
|
||||
pub(crate) total_tap_count: u32,
|
||||
pub(crate) word_counters_json: String,
|
||||
pub(crate) started_at_ms: i64,
|
||||
pub(crate) updated_at_ms: i64,
|
||||
pub(crate) finished_at_ms: i64,
|
||||
pub(crate) snapshot_json: String,
|
||||
pub(crate) created_at: Timestamp,
|
||||
pub(crate) updated_at: Timestamp,
|
||||
}
|
||||
|
||||
#[spacetimedb::table(
|
||||
accessor = wooden_fish_event,
|
||||
index(accessor = by_wooden_fish_event_profile_id, btree(columns = [profile_id])),
|
||||
index(accessor = by_wooden_fish_event_run_id, btree(columns = [run_id]))
|
||||
)]
|
||||
pub struct WoodenFishEventRow {
|
||||
#[primary_key]
|
||||
pub(crate) event_id: String,
|
||||
pub(crate) owner_user_id: String,
|
||||
pub(crate) profile_id: String,
|
||||
pub(crate) run_id: String,
|
||||
pub(crate) event_type: String,
|
||||
pub(crate) result: String,
|
||||
pub(crate) occurred_at: Timestamp,
|
||||
}
|
||||
254
server-rs/crates/spacetime-module/src/wooden_fish/types.rs
Normal file
254
server-rs/crates/spacetime-module/src/wooden_fish/types.rs
Normal file
@@ -0,0 +1,254 @@
|
||||
use crate::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub const WOODEN_FISH_TEMPLATE_ID: &str = "wooden-fish";
|
||||
pub const WOODEN_FISH_TEMPLATE_NAME: &str = "敲木鱼";
|
||||
pub const WOODEN_FISH_STAGE_COLLECTING: &str = "Collecting";
|
||||
pub const WOODEN_FISH_STAGE_DRAFT_COMPILED: &str = "DraftCompiled";
|
||||
pub const WOODEN_FISH_STAGE_PUBLISHED: &str = "Published";
|
||||
pub const WOODEN_FISH_PUBLICATION_DRAFT: &str = "Draft";
|
||||
pub const WOODEN_FISH_PUBLICATION_PUBLISHED: &str = "Published";
|
||||
pub const WOODEN_FISH_GENERATION_DRAFT: &str = "draft";
|
||||
pub const WOODEN_FISH_GENERATION_READY: &str = "ready";
|
||||
pub const WOODEN_FISH_EVENT_RUN_STARTED: &str = "run-started";
|
||||
pub const WOODEN_FISH_EVENT_RUN_CHECKPOINT: &str = "checkpoint";
|
||||
pub const WOODEN_FISH_EVENT_RUN_FINISHED: &str = "finish";
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
|
||||
pub struct WoodenFishAgentSessionCreateInput {
|
||||
pub session_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub work_title: String,
|
||||
pub work_description: String,
|
||||
pub theme_tags_json: Option<String>,
|
||||
pub config_json: Option<String>,
|
||||
pub draft_json: Option<String>,
|
||||
pub created_at_micros: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
|
||||
pub struct WoodenFishAgentSessionGetInput {
|
||||
pub session_id: String,
|
||||
pub owner_user_id: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
|
||||
pub struct WoodenFishDraftCompileInput {
|
||||
pub session_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub profile_id: String,
|
||||
pub author_display_name: String,
|
||||
pub work_title: String,
|
||||
pub work_description: String,
|
||||
pub theme_tags_json: Option<String>,
|
||||
pub hit_object_prompt: String,
|
||||
pub hit_object_reference_image_src: Option<String>,
|
||||
pub hit_sound_prompt: Option<String>,
|
||||
pub hit_object_asset_json: Option<String>,
|
||||
pub hit_sound_asset_json: Option<String>,
|
||||
pub floating_words_json: Option<String>,
|
||||
pub cover_image_src: Option<String>,
|
||||
pub generation_status: Option<String>,
|
||||
pub compiled_at_micros: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
|
||||
pub struct WoodenFishWorkUpdateInput {
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub work_title: String,
|
||||
pub work_description: String,
|
||||
pub theme_tags_json: String,
|
||||
pub hit_object_prompt: Option<String>,
|
||||
pub hit_object_reference_image_src: Option<String>,
|
||||
pub hit_sound_prompt: Option<String>,
|
||||
pub hit_object_asset_json: Option<String>,
|
||||
pub hit_sound_asset_json: Option<String>,
|
||||
pub floating_words_json: Option<String>,
|
||||
pub cover_image_src: Option<String>,
|
||||
pub generation_status: Option<String>,
|
||||
pub updated_at_micros: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
|
||||
pub struct WoodenFishWorkPublishInput {
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub published_at_micros: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
|
||||
pub struct WoodenFishWorksListInput {
|
||||
pub owner_user_id: String,
|
||||
pub published_only: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
|
||||
pub struct WoodenFishWorkGetInput {
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
|
||||
pub struct WoodenFishRunStartInput {
|
||||
pub run_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub profile_id: String,
|
||||
pub client_event_id: String,
|
||||
pub started_at_ms: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
|
||||
pub struct WoodenFishRunGetInput {
|
||||
pub run_id: String,
|
||||
pub owner_user_id: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
|
||||
pub struct WoodenFishRunCheckpointInput {
|
||||
pub run_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub total_tap_count: u32,
|
||||
pub word_counters_json: String,
|
||||
pub client_event_id: String,
|
||||
pub checkpoint_at_ms: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, SpacetimeType)]
|
||||
pub struct WoodenFishRunFinishInput {
|
||||
pub run_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub total_tap_count: u32,
|
||||
pub word_counters_json: String,
|
||||
pub client_event_id: String,
|
||||
pub finished_at_ms: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, SpacetimeType)]
|
||||
pub struct WoodenFishAgentSessionProcedureResult {
|
||||
pub ok: bool,
|
||||
pub session: Option<WoodenFishAgentSessionSnapshot>,
|
||||
pub error_message: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, SpacetimeType)]
|
||||
pub struct WoodenFishWorkProcedureResult {
|
||||
pub ok: bool,
|
||||
pub work: Option<WoodenFishWorkSnapshot>,
|
||||
pub error_message: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, SpacetimeType)]
|
||||
pub struct WoodenFishWorksProcedureResult {
|
||||
pub ok: bool,
|
||||
pub items: Vec<WoodenFishWorkSnapshot>,
|
||||
pub error_message: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, SpacetimeType)]
|
||||
pub struct WoodenFishRunProcedureResult {
|
||||
pub ok: bool,
|
||||
pub run: Option<module_wooden_fish::WoodenFishRunSnapshot>,
|
||||
pub error_message: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishCreatorConfigSnapshot {
|
||||
pub work_title: String,
|
||||
pub work_description: String,
|
||||
pub theme_tags: Vec<String>,
|
||||
pub hit_object_prompt: String,
|
||||
#[serde(default)]
|
||||
pub hit_object_reference_image_src: Option<String>,
|
||||
#[serde(default)]
|
||||
pub hit_sound_prompt: Option<String>,
|
||||
pub floating_words: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishImageAssetSnapshot {
|
||||
pub asset_id: String,
|
||||
pub image_src: String,
|
||||
pub image_object_key: String,
|
||||
pub asset_object_id: String,
|
||||
pub generation_provider: String,
|
||||
pub prompt: String,
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishAudioAssetSnapshot {
|
||||
pub asset_id: String,
|
||||
pub audio_src: String,
|
||||
pub audio_object_key: String,
|
||||
pub asset_object_id: String,
|
||||
pub source: String,
|
||||
#[serde(default)]
|
||||
pub prompt: Option<String>,
|
||||
#[serde(default)]
|
||||
pub duration_ms: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishDraftSnapshot {
|
||||
pub template_id: String,
|
||||
pub template_name: String,
|
||||
pub profile_id: Option<String>,
|
||||
pub work_title: String,
|
||||
pub work_description: String,
|
||||
pub theme_tags: Vec<String>,
|
||||
pub hit_object_prompt: String,
|
||||
pub hit_object_reference_image_src: Option<String>,
|
||||
pub hit_sound_prompt: Option<String>,
|
||||
pub floating_words: Vec<String>,
|
||||
pub hit_object_asset: Option<WoodenFishImageAssetSnapshot>,
|
||||
pub hit_sound_asset: Option<WoodenFishAudioAssetSnapshot>,
|
||||
pub cover_image_src: Option<String>,
|
||||
pub generation_status: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishAgentSessionSnapshot {
|
||||
pub session_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub current_turn: u32,
|
||||
pub progress_percent: u32,
|
||||
pub stage: String,
|
||||
pub config: WoodenFishCreatorConfigSnapshot,
|
||||
pub draft: Option<WoodenFishDraftSnapshot>,
|
||||
pub published_profile_id: Option<String>,
|
||||
pub created_at_micros: i64,
|
||||
pub updated_at_micros: i64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, SpacetimeType)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct WoodenFishWorkSnapshot {
|
||||
pub work_id: String,
|
||||
pub profile_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub source_session_id: String,
|
||||
pub author_display_name: String,
|
||||
pub work_title: String,
|
||||
pub work_description: String,
|
||||
pub theme_tags: Vec<String>,
|
||||
pub hit_object_prompt: String,
|
||||
pub hit_object_reference_image_src: Option<String>,
|
||||
pub hit_sound_prompt: Option<String>,
|
||||
pub hit_object_asset: Option<WoodenFishImageAssetSnapshot>,
|
||||
pub hit_sound_asset: Option<WoodenFishAudioAssetSnapshot>,
|
||||
pub floating_words: Vec<String>,
|
||||
pub cover_image_src: String,
|
||||
pub publication_status: String,
|
||||
pub publish_ready: bool,
|
||||
pub play_count: u32,
|
||||
pub generation_status: String,
|
||||
pub updated_at_micros: i64,
|
||||
pub published_at_micros: Option<i64>,
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user