chore: add loadtest observability setup

This commit is contained in:
kdletters
2026-05-16 22:44:30 +08:00
parent 7f16e88e57
commit 0305b79440
55 changed files with 2867 additions and 1622 deletions

View File

@@ -70,3 +70,9 @@ GENARRATIVE_SPACETIME_TOKEN=""
GENARRATIVE_ADMIN_USERNAME=admin GENARRATIVE_ADMIN_USERNAME=admin
GENARRATIVE_ADMIN_PASSWORD=123456 GENARRATIVE_ADMIN_PASSWORD=123456
ADMIN_API_TARGET=http://127.0.0.1:3100 ADMIN_API_TARGET=http://127.0.0.1:3100
# OTLP
GENARRATIVE_OTEL_ENABLED=true
OTEL_SERVICE_NAME=genarrative-api
OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318
OTEL_RESOURCE_ATTRIBUTES=deployment.environment=local,service.namespace=genarrative

View File

@@ -16,6 +16,15 @@
--- ---
## 2026-05-16 api-server OpenTelemetry 统一补齐 traces metrics logs
- 背景:压测与运行观测需要把 HTTP、SpacetimeDB 调用和应用日志串起来,同时保留本地 `journalctl` / 文件日志做故障排障。
- 决策:`api-server` 通过 OTLP HTTP base endpoint 发送 traces、metrics 和 logsCollector 统一用 `otelcol-contrib``npm run otel:debug` 负责 debug 采集,`npm run otel:rider` 负责转发到 RiderRider 只是接收与可视化端,不直接替代 Collector。
- 日志口径Rider Logs 面板只展示 log event 自身字段,请求完成日志需要直接携带 `request_id`、HTTP method、规范化 route、scheme、path、status、status_class、latency 和 slow_request更完整的 request attributes 仍以 trace/span 为准。
- 影响范围:`server-rs/crates/shared-logging``server-rs/crates/api-server``scripts/run-otelcol.mjs`、压测与运维文档。
- 验证方式:`cargo test -p shared-logging --manifest-path server-rs/Cargo.toml generic_otlp_http_endpoint_expands_to_signal_paths``cargo test -p api-server --manifest-path server-rs/Cargo.toml observability_route_keeps_metrics_labels_low_cardinality``cargo test -p api-server --manifest-path server-rs/Cargo.toml resolve_request_scheme_uses_forwarded_proto_first_value``cargo check -p api-server --manifest-path server-rs/Cargo.toml`
- 关联文档:`docs/【开发运维】本地开发验证与生产运维-2026-05-15.md``scripts/loadtest/README.md`
## 2026-05-14 创作页图像输入统一封装为图像组件 ## 2026-05-14 创作页图像输入统一封装为图像组件
- 背景:拼图创作页已经具备“画面描述生图 / 多参考图生图 / 上传主图后 AI 重绘 / 上传主图后不重绘”四条路径,抓大鹅封面和后续创作页也会复用同一套交互;继续在页面内复制会导致参考图、预览、删除确认和重绘开关漂移。 - 背景:拼图创作页已经具备“画面描述生图 / 多参考图生图 / 上传主图后 AI 重绘 / 上传主图后不重绘”四条路径,抓大鹅封面和后续创作页也会复用同一套交互;继续在页面内复制会导致参考图、预览、删除确认和重绘开关漂移。

View File

@@ -195,6 +195,13 @@ npm run check:server-rs-ddd
- `docs/technical/SPACETIMEDB_TABLE_CATALOG.md` - `docs/technical/SPACETIMEDB_TABLE_CATALOG.md`
- `docs/technical/MAINCLOUD_REFERENCE_REMOVAL_POLICY_2026-05-06.md` - `docs/technical/MAINCLOUD_REFERENCE_REMOVAL_POLICY_2026-05-06.md`
## 生产压测与观测默认口径
- 作品列表 50 HTTP req/s 压测使用 `scripts/loadtest/README.md` 中的 K6 命令;当前脚本一次 iteration 请求两个公开列表接口,因此目标 50 HTTP req/s 对应 `PEAK_RPS=25`
- 生产 `api-server` 默认 backlog、worker threads、systemd 限制、Nginx upstream timing log 和 OTLP 开关以 `docs/【开发运维】本地开发验证与生产运维-2026-05-15.md` 为准。
- OpenTelemetry 现阶段可选发送 traces / metrics / logs但不会取代本地 `journalctl -u genarrative-api.service``logs/api-server/``/var/log/nginx/genarrative.*.log`
- 指标 label 不写 raw URI、userId、profileId 或 request_idrequest_id 只用于 trace/log 串联。
## 前端相关默认验证 ## 前端相关默认验证
前端修改后,应根据修改范围选择: 前端修改后,应根据修改范围选择:

View File

@@ -374,6 +374,14 @@
- 验证:请求返回 JSON相关页面不再出现 HTML parse 错误。 - 验证:请求返回 JSON相关页面不再出现 HTML parse 错误。
- 关联:`docs/technical/PROFILE_MAIN_ROUTE_VITE_PROXY_FIX_2026-05-02.md` - 关联:`docs/technical/PROFILE_MAIN_ROUTE_VITE_PROXY_FIX_2026-05-02.md`
## `npm run build` 因 Vite warning 被 build-gate 判失败
- 现象:主站或后台 Vite 已经输出 `built in ...`,但根命令最后仍失败并打印 `Build gate failed because warnings were emitted`
- 原因:`scripts/build-gate.mjs` 会收集 stdout / stderr 中的 warning 行并作为硬失败;常见触发是产物 chunk 超过 `vite.config.ts``apps/admin-web/vite.config.ts``chunkSizeWarningLimit`
- 处理:先看 warning 原文确认来源。若是合理的入口级 chunk 体积增长,调整对应 Vite 配置阈值或做真实拆包;不要把这类失败按 Rust / SpacetimeDB 编译错误排查。
- 验证:重新执行 `npm run build`,主站与后台均构建完成且没有 build-gate warning 汇总。
- 关联:`scripts/build-gate.mjs``vite.config.ts``apps/admin-web/vite.config.ts`
## 反馈页清空 file input 前必须先拷贝 FileList ## 反馈页清空 file input 前必须先拷贝 FileList
- 现象:点击上传凭证会打开文件选择框,但选择图片后页面没有展示预览,提交时也没有携带图片凭证。 - 现象:点击上传凭证会打开文件选择框,但选择图片后页面没有展示预览,提交时也没有携带图片凭证。

10
.idea/.gitignore generated vendored
View File

@@ -1,10 +0,0 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# 已忽略包含查询文件的默认文件夹
/queries/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

1
.idea/.name generated
View File

@@ -1 +0,0 @@
mod.rs

View File

@@ -1,59 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<HTMLCodeStyleSettings>
<option name="HTML_SPACE_INSIDE_EMPTY_TAG" value="true" />
</HTMLCodeStyleSettings>
<JSCodeStyleSettings version="0">
<option name="FORCE_SEMICOLON_STYLE" value="true" />
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
<option name="USE_DOUBLE_QUOTES" value="false" />
<option name="FORCE_QUOTE_STYlE" value="true" />
<option name="ENFORCE_TRAILING_COMMA" value="WhenMultiline" />
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
<option name="SPACES_WITHIN_IMPORTS" value="true" />
</JSCodeStyleSettings>
<TypeScriptCodeStyleSettings version="0">
<option name="FORCE_SEMICOLON_STYLE" value="true" />
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
<option name="USE_DOUBLE_QUOTES" value="false" />
<option name="FORCE_QUOTE_STYlE" value="true" />
<option name="ENFORCE_TRAILING_COMMA" value="WhenMultiline" />
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
<option name="SPACES_WITHIN_IMPORTS" value="true" />
</TypeScriptCodeStyleSettings>
<VueCodeStyleSettings>
<option name="INTERPOLATION_NEW_LINE_AFTER_START_DELIMITER" value="false" />
<option name="INTERPOLATION_NEW_LINE_BEFORE_END_DELIMITER" value="false" />
</VueCodeStyleSettings>
<codeStyleSettings language="HTML">
<option name="SOFT_MARGINS" value="80" />
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="JavaScript">
<option name="SOFT_MARGINS" value="80" />
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="TypeScript">
<option name="SOFT_MARGINS" value="80" />
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="Vue">
<option name="SOFT_MARGINS" value="80" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>

View File

@@ -1,5 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

248
.idea/editor.xml generated
View File

@@ -1,248 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="BackendCodeEditorSettings">
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CDeclarationWithImplicitIntType/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CommentTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConstevalIfIsAlwaysConstant/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAbstractClassWithoutSpecifier/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAbstractFinalClass/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAbstractVirtualFunctionCallInCtor/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAccessSpecifierWithNoDeclarations/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppAwaiterTypeIsNotClass/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBooleanIncrementExpression/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatBadCode/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatLegacyCode/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatMixedArgs/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatTooFewArgs/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppBoostFormatTooManyArgs/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCStyleCast/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCVQualifierCanNotBeAppliedToReference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassCanBeFinal/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassIsIncomplete/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeedsConstructorBecauseOfUninitializedMember/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppClassNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCompileTimeConstantCanBeReplacedWithBooleanConstant/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConceptNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConditionalExpressionCanBeSimplified/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConstParameterInDeclaration/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppConstValueFunctionReturnType/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppCoroutineCallResolveError/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAArrayIndexOutOfBounds/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantConditions/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantFunctionResult/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAConstantParameter/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFADeletedPointer/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAEndlessLoop/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAInfiniteRecursion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAInvalidatedMemory/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALocalValueEscapesFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALocalValueEscapesScope/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFALoopConditionNotUpdated/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAMemoryLeak/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFANotInitializedField/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFANullDereference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFATimeOver/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnreachableCode/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnreachableFunctionCall/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnreadVariable/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDFAUnusedValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclarationHidesLocal/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclarationHidesUncapturedLocal/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclarationSpecifierWithoutDeclarators/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorDisambiguatedAsFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeclaratorUsedBeforeInitialization/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultCaseNotHandledInSwitchStatement/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultInitializationWithNoUserConstructor/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultIsUsedAsIdentifier/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDefaultedSpecialMemberFunctionIsImplicitlyDeleted/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeletingVoidPointer/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDependentTemplateWithoutTemplateKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDependentTypeWithoutTypenameKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeprecatedEntity/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeprecatedOverridenMethod/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDeprecatedRegisterStorageClassSpecifier/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDereferenceOperatorLimitExceeded/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDiscardedPostfixOperatorResult/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenSyntaxError/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenUndocumentedParameter/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppDoxygenUnresolvedReference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEmptyDeclaration/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceCVQualifiersOrder/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceCVQualifiersPlacement/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceDoStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceForStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceFunctionDeclarationStyle/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceIfStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceNestedNamespacesStyle/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceOverridingDestructorStyle/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceOverridingFunctionStyle/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceTypeAliasCodeStyle/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnforceWhileStatementBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEntityAssignedButNoRead/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEntityUsedOnlyInUnevaluatedContext/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEnumeratorNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEqualOperandsInBinaryExpression/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppEvaluationFailure/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppExplicitSpecializationInNonNamespaceScope/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppExpressionWithoutSideEffects/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFinalFunctionInFinalClass/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFinalNonOverridingVirtualFunction/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppForLoopCanBeReplacedWithWhile/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppForwardEnumDeclarationWithoutUnderlyingType/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionDoesntReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionIsNotImplemented/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionResultShouldBeUsed/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppFunctionalStyleCast/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppHeaderHasBeenAlreadyIncluded/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppHiddenFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppHidingFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIdenticalOperandsInBinaryExpression/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIfCanBeReplacedByConstexprIf/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppImplicitDefaultConstructorNotAvailable/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIncompatiblePointerConversion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIncompleteSwitchStatement/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppInconsistentNaming/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppIntegralToPointerConversion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppInvalidLineContinuation/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppJoinDeclarationAndAssignment/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLambdaCaptureNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableMayBeConst/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLocalVariableWithNonTrivialDtorIsNeverUsed/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppLongFloat/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberFunctionMayBeConst/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberFunctionMayBeStatic/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMemberInitializersOrder/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMismatchedClassTags/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingIncludeGuard/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMissingKeywordThrow/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppModulePartitionWithSeveralPartitionUnits/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtAddressOfClassRValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtBindingRValueToLvalueReference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtCopyElisionInCopyInitDeclarator/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtDoubleUserConversionInCopyInit/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtNotInitializedStaticConstLocalVar/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMsExtReinterpretCastFromNullptr/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMultiCharacterLiteral/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMultiCharacterWideLiteral/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMustBePublicVirtualToImplementInterface/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppMutableSpecifierOnReferenceMember/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNoDiscardExpression/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNodiscardFunctionWithoutReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExceptionSafeResourceAcquisition/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExplicitConversionOperator/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonExplicitConvertingConstructor/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonInlineFunctionDefinitionInHeaderFile/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNonInlineVariableDefinitionInHeaderFile/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppNotAllPathsReturnValue/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppObjectMemberMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppOutParameterMustBeWritten/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterMayBeConst/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterMayBeConstPtrOrRef/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterNamesMismatch/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppParameterNeverUsed/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPassValueParameterByConstReference/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPointerConversionDropsQualifiers/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPointerToIntegralConversion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPolymorphicClassWithNonVirtualPublicDestructor/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyErroneousEmptyStatements/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyUninitializedMember/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPossiblyUnintendedObjectSlicing/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrecompiledHeaderIsNotIncluded/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrecompiledHeaderNotFound/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfBadFormat/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfExtraArg/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfMissedArg/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrintfRiskyFormat/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppPrivateSpecialMemberFunctionIsNotImplemented/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRangeBasedForIncompatibleReference/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedefinitionOfDefaultArgumentInOverrideFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantAccessSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantBaseClassAccessSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantBaseClassInitializer/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantBooleanExpressionArgument/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantCastExpression/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantComplexityInComparison/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantConditionalExpression/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantConstSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantControlFlowJump/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantDereferencingAndTakingAddress/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantElaboratedTypeSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantElseKeyword/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantElseKeywordInsideCompoundStatement/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantEmptyDeclaration/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantEmptyStatement/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantExportKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantFwdClassOrEnumSpecifier/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantInlineSpecifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantLambdaParameterList/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantMemberInitializer/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantNamespaceDefinition/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantParentheses/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantQualifier/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantQualifierADL/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantStaticSpecifierOnMemberAllocationFunction/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantStaticSpecifierOnThreadLocalLocalVariable/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTemplateArguments/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTemplateKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantTypenameKeyword/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantVoidArgumentList/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRedundantZeroInitializerInAggregateInitialization/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReinterpretCastFromVoidPtr/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppRemoveRedundantBraces/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReplaceMemsetWithZeroInitialization/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReplaceTieWithStructuredBinding/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppReturnNoValueInNonVoidFunction/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSmartPointerVsMakeFunction/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSomeObjectMembersMightNotBeInitialized/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppSpecialFunctionWithoutNoexceptSpecification/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticAssertFailure/@EntryIndexedValue" value="ERROR" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticDataMemberInUnnamedStruct/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStaticSpecifierOnAnonymousNamespaceMember/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppStringLiteralToCharPointerConversion/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTabsAreDisallowed/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateArgumentsCanBeDeduced/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateParameterNeverUsed/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTemplateParameterShadowing/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppThrowExpressionCanBeReplacedWithRethrow/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTooWideScope/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTooWideScopeInitStatement/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppTypeAliasNeverUsed/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUninitializedDependentBaseClass/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUninitializedNonStaticDataMember/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnionMemberOfReferenceType/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnmatchedPragmaEndRegionDirective/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnmatchedPragmaRegionDirective/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnnamedNamespaceInHeaderFile/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnnecessaryWhitespace/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnsignedZeroComparison/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUnusedIncludeDirective/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAlgorithmWithCount/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAssociativeContains/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAuto/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseAutoForNumeric/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseElementsView/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseEraseAlgorithm/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseFamiliarTemplateSyntaxForGenericLambdas/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseRangeAlgorithm/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseStdSize/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseStructuredBinding/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUseTypeTraitAlias/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUserDefinedLiteralSuffixDoesNotStartWithUnderscore/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppUsingResultOfAssignmentAsCondition/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVariableCanBeMadeConstexpr/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVirtualFunctionCallInsideCtor/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVirtualFunctionInFinalClass/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppVolatileParameterInDeclaration/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppWarningDirective/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppWrongIncludesOrder/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppWrongSlashesInIncludeDirective/@EntryIndexedValue" value="HINT" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppZeroConstantCanBeReplacedWithNullptr/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=CppZeroValuedExpressionUsedAsNullPointer/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=IdentifierTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=IfStdIsConstantEvaluatedCanBeReplaced/@EntryIndexedValue" value="SUGGESTION" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=StdIsConstantEvaluatedWillAlwaysEvaluateToConstant/@EntryIndexedValue" value="WARNING" type="string" />
<option name="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringLiteralTypo/@EntryIndexedValue" value="DO_NOT_SHOW" type="string" />
</component>
</project>

View File

@@ -1,6 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

8
.idea/modules.xml generated
View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/Genarrative.iml" filepath="$PROJECT_DIR$/.idea/Genarrative.iml" />
</modules>
</component>
</project>

6
.idea/prettier.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PrettierConfiguration">
<option name="myConfigurationMode" value="AUTOMATIC" />
</component>
</project>

6
.idea/vcs.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@@ -5,6 +5,12 @@ GENARRATIVE_ENV=production
GENARRATIVE_API_HOST=127.0.0.1 GENARRATIVE_API_HOST=127.0.0.1
GENARRATIVE_API_PORT=8082 GENARRATIVE_API_PORT=8082
GENARRATIVE_API_LOG=info,tower_http=info GENARRATIVE_API_LOG=info,tower_http=info
GENARRATIVE_API_LISTEN_BACKLOG=1024
GENARRATIVE_API_WORKER_THREADS=4
GENARRATIVE_OTEL_ENABLED=false
OTEL_SERVICE_NAME=genarrative-api
OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318
OTEL_RESOURCE_ATTRIBUTES=deployment.environment=production,service.namespace=genarrative
GENARRATIVE_ADMIN_USERNAME= GENARRATIVE_ADMIN_USERNAME=
GENARRATIVE_ADMIN_PASSWORD= GENARRATIVE_ADMIN_PASSWORD=

View File

@@ -1,9 +1,23 @@
# 开发服无域名时使用的 HTTP 入口,只允许用于 DEPLOY_TARGET=development。 # 开发服无域名时使用的 HTTP 入口,只允许用于 DEPLOY_TARGET=development。
# 没有域名时,将 SERVER_NAME 填为开发机 IP 或临时主机名。 # 没有域名时,将 SERVER_NAME 填为开发机 IP 或临时主机名。
# 生产 release 仍必须使用 genarrative.conf 的 HTTPS 配置。 # 生产 release 仍必须使用 genarrative.conf 的 HTTPS 配置。
log_format genarrative_upstream
'$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" "$http_user_agent" '
'request_time=$request_time upstream_connect_time=$upstream_connect_time '
'upstream_header_time=$upstream_header_time upstream_response_time=$upstream_response_time '
'upstream_status=$upstream_status request_id=$request_id';
upstream genarrative_api {
server 127.0.0.1:8082;
keepalive 64;
}
server { server {
listen 80; listen 80;
server_name genarrative.example.com; server_name genarrative.example.com;
access_log /var/log/nginx/genarrative.access.log genarrative_upstream;
error_log /var/log/nginx/genarrative.error.log warn;
gzip on; gzip on;
gzip_vary on; gzip_vary on;
@@ -34,8 +48,9 @@ server {
return 503 '{"ok":false,"error":{"code":"MAINTENANCE","message":"服务维护中"}}'; return 503 '{"ok":false,"error":{"code":"MAINTENANCE","message":"服务维护中"}}';
} }
proxy_pass http://127.0.0.1:8082/admin/api/; proxy_pass http://genarrative_api/admin/api/;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -73,12 +88,13 @@ server {
return 503 '{"ok":false,"error":{"code":"MAINTENANCE","message":"服务维护中"}}'; return 503 '{"ok":false,"error":{"code":"MAINTENANCE","message":"服务维护中"}}';
} }
proxy_pass http://127.0.0.1:8082; proxy_pass http://genarrative_api;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_buffering off; proxy_buffering off;
proxy_read_timeout 3600s; proxy_read_timeout 3600s;
proxy_send_timeout 3600s; proxy_send_timeout 3600s;
add_header X-Accel-Buffering no always; add_header X-Accel-Buffering no always;
proxy_set_header Connection "";
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

View File

@@ -1,7 +1,21 @@
# 生产域名需要在部署前替换为真实域名,并由 certbot 或等价流程写入 HTTPS 证书配置。 # 生产域名需要在部署前替换为真实域名,并由 certbot 或等价流程写入 HTTPS 证书配置。
log_format genarrative_upstream
'$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" "$http_user_agent" '
'request_time=$request_time upstream_connect_time=$upstream_connect_time '
'upstream_header_time=$upstream_header_time upstream_response_time=$upstream_response_time '
'upstream_status=$upstream_status request_id=$request_id';
upstream genarrative_api {
server 127.0.0.1:8082;
keepalive 64;
}
server { server {
listen 80; listen 80;
server_name genarrative.example.com; server_name genarrative.example.com;
access_log /var/log/nginx/genarrative.access.log genarrative_upstream;
error_log /var/log/nginx/genarrative.error.log warn;
location /.well-known/acme-challenge/ { location /.well-known/acme-challenge/ {
root /var/www/html; root /var/www/html;
@@ -15,6 +29,8 @@ server {
server { server {
listen 443 ssl http2; listen 443 ssl http2;
server_name genarrative.example.com; server_name genarrative.example.com;
access_log /var/log/nginx/genarrative.access.log genarrative_upstream;
error_log /var/log/nginx/genarrative.error.log warn;
gzip on; gzip on;
gzip_vary on; gzip_vary on;
@@ -48,8 +64,9 @@ server {
return 503 '{"ok":false,"error":{"code":"MAINTENANCE","message":"服务维护中"}}'; return 503 '{"ok":false,"error":{"code":"MAINTENANCE","message":"服务维护中"}}';
} }
proxy_pass http://127.0.0.1:8082/admin/api/; proxy_pass http://genarrative_api/admin/api/;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -87,12 +104,13 @@ server {
return 503 '{"ok":false,"error":{"code":"MAINTENANCE","message":"服务维护中"}}'; return 503 '{"ok":false,"error":{"code":"MAINTENANCE","message":"服务维护中"}}';
} }
proxy_pass http://127.0.0.1:8082; proxy_pass http://genarrative_api;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_buffering off; proxy_buffering off;
proxy_read_timeout 3600s; proxy_read_timeout 3600s;
proxy_send_timeout 3600s; proxy_send_timeout 3600s;
add_header X-Accel-Buffering no always; add_header X-Accel-Buffering no always;
proxy_set_header Connection "";
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

View File

@@ -15,6 +15,8 @@ Restart=always
RestartSec=5 RestartSec=5
KillSignal=SIGINT KillSignal=SIGINT
TimeoutStopSec=30 TimeoutStopSec=30
LimitNOFILE=65535
TasksMax=2048
# api-server 只读发布目录,运行态写入必须显式落到环境变量指定的服务端私有目录。 # api-server 只读发布目录,运行态写入必须显式落到环境变量指定的服务端私有目录。
NoNewPrivileges=true NoNewPrivileges=true

View File

@@ -79,6 +79,8 @@ npm run lint
npm run check npm run check
``` ```
`npm run build``scripts/build-gate.mjs` 串行构建主站和后台;该门禁会把 Vite warning 当成失败处理。若看到 `Build gate failed because warnings were emitted`,先看 warning 原文,例如 chunk 体积超过 `vite.config.ts` / `apps/admin-web/vite.config.ts``chunkSizeWarningLimit`,不要先按 Rust 编译失败排查。
视觉小说负向扫描与验收门禁: 视觉小说负向扫描与验收门禁:
```bash ```bash
@@ -149,6 +151,25 @@ Jenkins 按 web / api / Spacetime module / build / deploy / publish 拆分
生产环境变量模板:`deploy/env/api-server.env.example`。真实密钥只放服务器,不提交 Git不写入文档示例。 生产环境变量模板:`deploy/env/api-server.env.example`。真实密钥只放服务器,不提交 Git不写入文档示例。
50 HTTP req/s 首版压测优化口径:
- `api-server` 生产模板默认 `GENARRATIVE_API_LISTEN_BACKLOG=1024``GENARRATIVE_API_WORKER_THREADS=4`;本地未设置 worker threads 时继续使用 Tokio 默认值。
- `genarrative-api.service` 设置 `LimitNOFILE=65535``TasksMax=2048`;上线后用 `systemctl show genarrative-api.service -p LimitNOFILE -p TasksMax``cat /proc/$(pidof api-server)/limits` 核对。
- Nginx `/api/``/admin/api/` 通过 `genarrative_api` upstream 代理到 `127.0.0.1:8082`upstream keepalive 为 64压测时看 `/var/log/nginx/genarrative.access.log` 中的 `request_time``upstream_connect_time``upstream_header_time``upstream_response_time``upstream_status``request_id`
- 作品列表 K6 脚本一次 iteration 默认请求两个公开接口,因此约 50 HTTP req/s 的目标命令使用 `SCENARIO=spike START_RPS=5 PEAK_RPS=25 HOLD=60s END_RPS=5 DETAIL_RATIO=0 npm run loadtest:k6:works`
- 50 HTTP req/s 验收目标为 `http_req_failed < 1%``p95 < 2s``dropped_iterations = 0`,同时压测窗口内 Nginx 无新增 502。
OpenTelemetry 现阶段可选 OTLP traces / metrics / logs但本地日志与 Nginx 文件日志仍保留:
- 默认 `GENARRATIVE_OTEL_ENABLED=false`,未开启时 api-server 不依赖 Collector。
- Collector 使用官方 `otelcol-contrib`,只监听 `127.0.0.1:4317/4318`;本地用 `npm run otel:debug` 启动 debug exporter`npm run otel:rider` 转发到 Rider再接 Jaeger、Tempo、Prometheus、Grafana 或托管平台。
- api-server 开启时使用 `OTEL_SERVICE_NAME=genarrative-api``OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318`
- api-server 当前发 OTLP HTTP`OTEL_EXPORTER_OTLP_ENDPOINT` 指向 Collector HTTP base endpoint不要改到 gRPC `4317` 或 Rider 端口Rider 由 Collector 通过 `RIDER_OTLP_GRPC_ENDPOINT` 转发。
- 应用日志仍通过 `journalctl -u genarrative-api.service` 查看Nginx 日志仍写文件;日志等级继续用 `GENARRATIVE_API_LOG` / `RUST_LOG` 控制,例如 `info,tower_http=info,spacetime_client=info`
- debug exporter / Rider 转发都会同时接收 traces、metrics 和 logs。
- Rider 的 Logs 面板只展示 log event 自身字段,不会自动展开父 span 的全部 attributes请求完成日志会直接带 `request_id``http.request.method``http.route``url.scheme``url.path``http.response.status_code``status_class``latency_ms``slow_request`,完整链路继续到 Traces 面板按 trace/span 查看。
- 指标 label 只允许低基数字段HTTP 使用 `method``route``status_class`SpacetimeDB 调用使用 `procedure``status_class``request_id` 只进入 trace/log attribute不进入 metric label。
常见外部服务变量: 常见外部服务变量:
- `GENARRATIVE_SPACETIME_SERVER_URL` - `GENARRATIVE_SPACETIME_SERVER_URL`

78
package-lock.json generated
View File

@@ -72,6 +72,7 @@
"version": "7.29.0", "version": "7.29.0",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz",
"integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
"peer": true,
"dependencies": { "dependencies": {
"@babel/code-frame": "^7.29.0", "@babel/code-frame": "^7.29.0",
"@babel/generator": "^7.29.0", "@babel/generator": "^7.29.0",
@@ -1515,7 +1516,6 @@
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
"dev": true, "dev": true,
"peer": true,
"engines": { "engines": {
"node": ">=10" "node": ">=10"
}, },
@@ -1528,7 +1528,6 @@
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
"integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
"dev": true, "dev": true,
"peer": true,
"dependencies": { "dependencies": {
"ansi-regex": "^5.0.1", "ansi-regex": "^5.0.1",
"ansi-styles": "^5.0.0", "ansi-styles": "^5.0.0",
@@ -1542,8 +1541,7 @@
"version": "17.0.2", "version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
"dev": true, "dev": true
"peer": true
}, },
"node_modules/@testing-library/react": { "node_modules/@testing-library/react": {
"version": "16.3.2", "version": "16.3.2",
@@ -1606,8 +1604,7 @@
"version": "5.0.4", "version": "5.0.4",
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
"integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
"dev": true, "dev": true
"peer": true
}, },
"node_modules/@types/babel__core": { "node_modules/@types/babel__core": {
"version": "7.20.5", "version": "7.20.5",
@@ -1650,7 +1647,8 @@
"version": "4.3.20", "version": "4.3.20",
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.20.tgz", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.20.tgz",
"integrity": "sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==", "integrity": "sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==",
"dev": true "dev": true,
"peer": true
}, },
"node_modules/@types/chai-subset": { "node_modules/@types/chai-subset": {
"version": "1.3.6", "version": "1.3.6",
@@ -1696,6 +1694,7 @@
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
"integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
"dev": true, "dev": true,
"peer": true,
"dependencies": { "dependencies": {
"csstype": "^3.2.2" "csstype": "^3.2.2"
} }
@@ -1705,6 +1704,7 @@
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
"integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
"dev": true, "dev": true,
"peer": true,
"peerDependencies": { "peerDependencies": {
"@types/react": "^19.2.0" "@types/react": "^19.2.0"
} }
@@ -1796,6 +1796,7 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz",
"integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
"dev": true, "dev": true,
"peer": true,
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/scope-manager": "6.21.0",
"@typescript-eslint/types": "6.21.0", "@typescript-eslint/types": "6.21.0",
@@ -2126,6 +2127,7 @@
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
"dev": true, "dev": true,
"peer": true,
"bin": { "bin": {
"acorn": "bin/acorn" "acorn": "bin/acorn"
}, },
@@ -2216,7 +2218,6 @@
"integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"dependencies": { "dependencies": {
"dequal": "^2.0.3" "dequal": "^2.0.3"
} }
@@ -2338,6 +2339,7 @@
"url": "https://github.com/sponsors/ai" "url": "https://github.com/sponsors/ai"
} }
], ],
"peer": true,
"dependencies": { "dependencies": {
"baseline-browser-mapping": "^2.9.0", "baseline-browser-mapping": "^2.9.0",
"caniuse-lite": "^1.0.30001759", "caniuse-lite": "^1.0.30001759",
@@ -2629,7 +2631,6 @@
"integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=6" "node": ">=6"
} }
@@ -2685,8 +2686,7 @@
"version": "0.5.16", "version": "0.5.16",
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
"integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
"dev": true, "dev": true
"peer": true
}, },
"node_modules/domexception": { "node_modules/domexception": {
"version": "4.0.0", "version": "4.0.0",
@@ -2873,6 +2873,7 @@
"integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
"dev": true, "dev": true,
"peer": true,
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1", "@eslint-community/regexpp": "^4.6.1",
@@ -3697,6 +3698,7 @@
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz",
"integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==", "integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==",
"dev": true, "dev": true,
"peer": true,
"dependencies": { "dependencies": {
"abab": "^2.0.6", "abab": "^2.0.6",
"cssstyle": "^3.0.0", "cssstyle": "^3.0.0",
@@ -4096,7 +4098,6 @@
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
"integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
"dev": true, "dev": true,
"peer": true,
"bin": { "bin": {
"lz-string": "bin/bin.js" "lz-string": "bin/bin.js"
} }
@@ -4435,6 +4436,7 @@
"version": "4.0.3", "version": "4.0.3",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"peer": true,
"engines": { "engines": {
"node": ">=12" "node": ">=12"
}, },
@@ -4486,6 +4488,7 @@
"url": "https://github.com/sponsors/ai" "url": "https://github.com/sponsors/ai"
} }
], ],
"peer": true,
"dependencies": { "dependencies": {
"nanoid": "^3.3.11", "nanoid": "^3.3.11",
"picocolors": "^1.1.1", "picocolors": "^1.1.1",
@@ -4619,6 +4622,7 @@
"version": "19.2.4", "version": "19.2.4",
"resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz",
"integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==",
"peer": true,
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
} }
@@ -4627,6 +4631,7 @@
"version": "19.2.4", "version": "19.2.4",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz",
"integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==",
"peer": true,
"dependencies": { "dependencies": {
"scheduler": "^0.27.0" "scheduler": "^0.27.0"
}, },
@@ -5074,6 +5079,7 @@
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz",
"integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==",
"devOptional": true, "devOptional": true,
"peer": true,
"dependencies": { "dependencies": {
"esbuild": "~0.27.0", "esbuild": "~0.27.0",
"get-tsconfig": "^4.7.5" "get-tsconfig": "^4.7.5"
@@ -5126,6 +5132,7 @@
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
"dev": true, "dev": true,
"peer": true,
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
"tsserver": "bin/tsserver" "tsserver": "bin/tsserver"
@@ -5207,6 +5214,7 @@
"version": "6.4.1", "version": "6.4.1",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz",
"integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
"peer": true,
"dependencies": { "dependencies": {
"esbuild": "^0.25.0", "esbuild": "^0.25.0",
"fdir": "^6.4.4", "fdir": "^6.4.4",
@@ -7027,6 +7035,7 @@
"version": "7.29.0", "version": "7.29.0",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz",
"integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
"peer": true,
"requires": { "requires": {
"@babel/code-frame": "^7.29.0", "@babel/code-frame": "^7.29.0",
"@babel/generator": "^7.29.0", "@babel/generator": "^7.29.0",
@@ -7835,15 +7844,13 @@
"version": "5.2.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
"dev": true, "dev": true
"peer": true
}, },
"pretty-format": { "pretty-format": {
"version": "27.5.1", "version": "27.5.1",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
"integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
"dev": true, "dev": true,
"peer": true,
"requires": { "requires": {
"ansi-regex": "^5.0.1", "ansi-regex": "^5.0.1",
"ansi-styles": "^5.0.0", "ansi-styles": "^5.0.0",
@@ -7854,8 +7861,7 @@
"version": "17.0.2", "version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
"dev": true, "dev": true
"peer": true
} }
} }
}, },
@@ -7891,8 +7897,7 @@
"version": "5.0.4", "version": "5.0.4",
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
"integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
"dev": true, "dev": true
"peer": true
}, },
"@types/babel__core": { "@types/babel__core": {
"version": "7.20.5", "version": "7.20.5",
@@ -7935,7 +7940,8 @@
"version": "4.3.20", "version": "4.3.20",
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.20.tgz", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.20.tgz",
"integrity": "sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==", "integrity": "sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==",
"dev": true "dev": true,
"peer": true
}, },
"@types/chai-subset": { "@types/chai-subset": {
"version": "1.3.6", "version": "1.3.6",
@@ -7978,6 +7984,7 @@
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
"integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
"dev": true, "dev": true,
"peer": true,
"requires": { "requires": {
"csstype": "^3.2.2" "csstype": "^3.2.2"
} }
@@ -7987,6 +7994,7 @@
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
"integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
"dev": true, "dev": true,
"peer": true,
"requires": {} "requires": {}
}, },
"@types/semver": { "@types/semver": {
@@ -8053,6 +8061,7 @@
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz",
"integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
"dev": true, "dev": true,
"peer": true,
"requires": { "requires": {
"@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/scope-manager": "6.21.0",
"@typescript-eslint/types": "6.21.0", "@typescript-eslint/types": "6.21.0",
@@ -8263,7 +8272,8 @@
"version": "8.16.0", "version": "8.16.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
"dev": true "dev": true,
"peer": true
}, },
"acorn-jsx": { "acorn-jsx": {
"version": "5.3.2", "version": "5.3.2",
@@ -8326,7 +8336,6 @@
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
"integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
"dev": true, "dev": true,
"peer": true,
"requires": { "requires": {
"dequal": "^2.0.3" "dequal": "^2.0.3"
} }
@@ -8396,6 +8405,7 @@
"version": "4.28.1", "version": "4.28.1",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz",
"integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
"peer": true,
"requires": { "requires": {
"baseline-browser-mapping": "^2.9.0", "baseline-browser-mapping": "^2.9.0",
"caniuse-lite": "^1.0.30001759", "caniuse-lite": "^1.0.30001759",
@@ -8605,8 +8615,7 @@
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
"integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
"dev": true, "dev": true
"peer": true
}, },
"detect-libc": { "detect-libc": {
"version": "2.1.2", "version": "2.1.2",
@@ -8646,8 +8655,7 @@
"version": "0.5.16", "version": "0.5.16",
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
"integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
"dev": true, "dev": true
"peer": true
}, },
"domexception": { "domexception": {
"version": "4.0.0", "version": "4.0.0",
@@ -8782,6 +8790,7 @@
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz",
"integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
"dev": true, "dev": true,
"peer": true,
"requires": { "requires": {
"@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1", "@eslint-community/regexpp": "^4.6.1",
@@ -9360,6 +9369,7 @@
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz",
"integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==", "integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==",
"dev": true, "dev": true,
"peer": true,
"requires": { "requires": {
"abab": "^2.0.6", "abab": "^2.0.6",
"cssstyle": "^3.0.0", "cssstyle": "^3.0.0",
@@ -9566,8 +9576,7 @@
"version": "1.5.0", "version": "1.5.0",
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
"integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
"dev": true, "dev": true
"peer": true
}, },
"magic-string": { "magic-string": {
"version": "0.30.21", "version": "0.30.21",
@@ -9813,7 +9822,8 @@
"picomatch": { "picomatch": {
"version": "4.0.3", "version": "4.0.3",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==" "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"peer": true
}, },
"pkg-types": { "pkg-types": {
"version": "1.3.1", "version": "1.3.1",
@@ -9843,6 +9853,7 @@
"version": "8.5.8", "version": "8.5.8",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz",
"integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==",
"peer": true,
"requires": { "requires": {
"nanoid": "^3.3.11", "nanoid": "^3.3.11",
"picocolors": "^1.1.1", "picocolors": "^1.1.1",
@@ -9926,12 +9937,14 @@
"react": { "react": {
"version": "19.2.4", "version": "19.2.4",
"resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz",
"integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==" "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==",
"peer": true
}, },
"react-dom": { "react-dom": {
"version": "19.2.4", "version": "19.2.4",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz",
"integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==",
"peer": true,
"requires": { "requires": {
"scheduler": "^0.27.0" "scheduler": "^0.27.0"
} }
@@ -10256,6 +10269,7 @@
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz",
"integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==",
"devOptional": true, "devOptional": true,
"peer": true,
"requires": { "requires": {
"esbuild": "~0.27.0", "esbuild": "~0.27.0",
"fsevents": "~2.3.3", "fsevents": "~2.3.3",
@@ -10287,7 +10301,8 @@
"version": "5.8.3", "version": "5.8.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
"dev": true "dev": true,
"peer": true
}, },
"ufo": { "ufo": {
"version": "1.6.3", "version": "1.6.3",
@@ -10339,6 +10354,7 @@
"version": "6.4.1", "version": "6.4.1",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz",
"integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==",
"peer": true,
"requires": { "requires": {
"esbuild": "^0.25.0", "esbuild": "^0.25.0",
"fdir": "^6.4.4", "fdir": "^6.4.4",

View File

@@ -10,6 +10,8 @@
"dev:web": "node scripts/dev.mjs web", "dev:web": "node scripts/dev.mjs web",
"dev:admin-web": "node scripts/dev.mjs admin-web", "dev:admin-web": "node scripts/dev.mjs admin-web",
"dev:spacetime:logs": "node scripts/run-bash-script.mjs scripts/spacetime-logs-local.sh", "dev:spacetime:logs": "node scripts/run-bash-script.mjs scripts/spacetime-logs-local.sh",
"otel:debug": "node scripts/run-otelcol.mjs debug",
"otel:rider": "node scripts/run-otelcol.mjs rider",
"admin-web:build": "node scripts/admin-web-build.mjs build", "admin-web:build": "node scripts/admin-web-build.mjs build",
"admin-web:typecheck": "node scripts/admin-web-build.mjs typecheck", "admin-web:typecheck": "node scripts/admin-web-build.mjs typecheck",
"admin-web:preview": "npm --prefix apps/admin-web run preview --", "admin-web:preview": "npm --prefix apps/admin-web run preview --",

View File

@@ -113,6 +113,17 @@ $env:WORKS_DATA="data/works-list.local.json"
npm run loadtest:k6:works -- --summary-trend-stats="avg,min,med,p(90),p(95),p(99),max" npm run loadtest:k6:works -- --summary-trend-stats="avg,min,med,p(90),p(95),p(99),max"
``` ```
## 50 HTTP req/s 口径
`k6-works-list.js` 默认一次 iteration 会依次请求两个公开列表接口:`/api/runtime/puzzle/gallery``/api/runtime/custom-world-gallery`。因此目标约 50 HTTP req/s 时,`ramping-arrival-rate``PEAK_RPS` 应设置为 `25`。如果传入 `AUTH_TOKEN` 或把 `DETAIL_RATIO` 设为大于 0每次 iteration 的请求数会增加,需要重新折算。
验收目标:
- `http_req_failed < 1%`
- `http_req_duration p95 < 2000ms`
- `dropped_iterations = 0`
- 压测窗口内 Nginx 无新增 502
## Smoke ## Smoke
```bash ```bash
@@ -151,17 +162,38 @@ BASE_URL=http://127.0.0.1:8787 \
WORKS_DATA=data/works-list.local.json \ WORKS_DATA=data/works-list.local.json \
SCENARIO=spike \ SCENARIO=spike \
START_RPS=5 \ START_RPS=5 \
PEAK_RPS=100 \ PEAK_RPS=25 \
HOLD=2m \ HOLD=60s \
DETAIL_RATIO=0 \ DETAIL_RATIO=0 \
npm run loadtest:k6:works npm run loadtest:k6:works
``` ```
默认阈值: 默认阈值:
- `http_req_failed < 5%` - `http_req_failed < 1%`
- `http_req_duration p95 < 2000ms` - `http_req_duration p95 < 2000ms`
- `works_list_shape_error_rate < 5%` - `dropped_iterations = 0`
- `works_list_shape_error_rate < 1%`
PowerShell
```powershell
$env:BASE_URL="https://genarrative.world"
$env:WORKS_DATA="data/works-list.local.json"
$env:SCENARIO="spike"
$env:START_RPS="5"
$env:PEAK_RPS="25"
$env:HOLD="60s"
$env:END_RPS="5"
$env:DETAIL_RATIO="0"
npm run loadtest:k6:works -- --summary-trend-stats="avg,min,med,p(90),p(95),p(99),max"
```
线上 release 回归可使用同一组环境变量:
```bash
SCENARIO=spike START_RPS=5 PEAK_RPS=25 HOLD=60s END_RPS=5 DETAIL_RATIO=0 npm run loadtest:k6:works
```
## 带登录态压测个人作品列表 ## 带登录态压测个人作品列表
@@ -197,6 +229,96 @@ npm run loadtest:k6:works
- 如果个人作品列表返回 401确认 `AUTH_TOKEN` 是当前 api-server 可识别的 access token。 - 如果个人作品列表返回 401确认 `AUTH_TOKEN` 是当前 api-server 可识别的 access token。
- 如果详情全部 404确认是否已向目标环境导入与 `WORKS_DATA` 一致的数据。 - 如果详情全部 404确认是否已向目标环境导入与 `WORKS_DATA` 一致的数据。
## 压测窗口采集
Nginx upstream timing
```bash
sudo tail -f /var/log/nginx/genarrative.access.log
sudo tail -f /var/log/nginx/genarrative.error.log
```
api-server 与 SpacetimeDB 日志:
```bash
sudo journalctl -u genarrative-api.service -f
sudo journalctl -u spacetimedb.service -f
```
api-server 的 OpenTelemetry 默认关闭。需要验证 OTLP traces / metrics / logs 时,先在服务器本机启动只监听 `127.0.0.1``otelcol-contrib` debug exporter
```bash
npm run otel:debug
```
如果要把本机数据转发给 Rider OpenTelemetry 面板,先在 Rider 的 OpenTelemetry 设置中启用固定 OTLP server port例如 `17011`,再运行:
```bash
RIDER_OTLP_GRPC_ENDPOINT=127.0.0.1:17011 npm run otel:rider
```
脚本会在 `.codex-temp/otelcol/` 生成临时 collector 配置,默认接收 api-server 发到 `http://127.0.0.1:4318` 的 OTLP HTTP 数据。需要改端口时可设置:
- `OTELCOL_OTLP_HTTP_ENDPOINT`,默认 `127.0.0.1:4318`
- `OTELCOL_OTLP_GRPC_ENDPOINT`,默认 `127.0.0.1:4317`
- `RIDER_OTLP_GRPC_ENDPOINT`,默认 `127.0.0.1:17011`
- `OTELCOL_BIN`,默认 `otelcol-contrib`
等价的 debug collector 配置如下:
```yaml
receivers:
otlp:
protocols:
grpc:
endpoint: 127.0.0.1:4317
http:
endpoint: 127.0.0.1:4318
exporters:
debug:
verbosity: detailed
service:
pipelines:
traces:
receivers: [otlp]
exporters: [debug]
metrics:
receivers: [otlp]
exporters: [debug]
logs:
receivers: [otlp]
exporters: [debug]
```
```bash
otelcol-contrib --config /etc/otelcol-contrib/genarrative-debug.yaml
```
然后在 `/etc/genarrative/api-server.env` 中打开:
```env
GENARRATIVE_OTEL_ENABLED=true
OTEL_SERVICE_NAME=genarrative-api
OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318
```
注意 `api-server` 当前使用 OTLP HTTP exporter`OTEL_EXPORTER_OTLP_ENDPOINT` 必须指向 Collector 的 HTTP base endpoint `http://127.0.0.1:4318`。不要把它改成 Collector gRPC 端口 `4317`,也不要直接指向 Rider 的 gRPC 端口Rider 只由 `npm run otel:rider` 启动的 Collector 通过 `RIDER_OTLP_GRPC_ENDPOINT` 转发。
OTLP logs 是远端观测增量不替代本地日志api-server 日志仍看 `journalctl` / `logs/api-server/`Nginx 日志仍看文件。日志等级继续用 `GENARRATIVE_API_LOG` / `RUST_LOG` 控制,例如 `info,tower_http=info,spacetime_client=info`
Rider 的 Logs 面板展示的是 OTLP log event 自身字段,不会自动把父 span 的全部 attributes 摊平到每一条日志。请求完成日志会直接携带 `request_id``http.request.method``http.route``url.scheme``url.path``http.response.status_code``status_class``latency_ms``slow_request`;更完整的请求链路仍在 Traces 面板中按同一个 trace/span 关联查看。
线上回归辅助命令:
```bash
systemctl show genarrative-api.service -p LimitNOFILE -p TasksMax
cat /proc/$(pidof api-server)/limits
ss -ltnp | grep 8082
curl -sS http://127.0.0.1:8082/healthz
```
## 验证命令 ## 验证命令
```bash ```bash

View File

@@ -56,20 +56,22 @@ const scenarioOptions = {
scenarios: { scenarios: {
spike: { spike: {
executor: 'ramping-arrival-rate', executor: 'ramping-arrival-rate',
startRate: Number(__ENV.START_RPS || 5),
preAllocatedVUs: Number(__ENV.PREALLOCATED_VUS || 50), preAllocatedVUs: Number(__ENV.PREALLOCATED_VUS || 50),
maxVUs: Number(__ENV.MAX_VUS || 200), maxVUs: Number(__ENV.MAX_VUS || 200),
timeUnit: '1s', timeUnit: '1s',
stages: [ stages: [
{ target: Number(__ENV.START_RPS || 5), duration: __ENV.RAMP_UP || '30s' }, { target: Number(__ENV.PEAK_RPS || 25), duration: __ENV.RAMP_UP || '30s' },
{ target: Number(__ENV.PEAK_RPS || 100), duration: __ENV.HOLD || '2m' }, { target: Number(__ENV.PEAK_RPS || 25), duration: __ENV.HOLD || '2m' },
{ target: Number(__ENV.END_RPS || 5), duration: __ENV.RAMP_DOWN || '30s' }, { target: Number(__ENV.END_RPS || 5), duration: __ENV.RAMP_DOWN || '30s' },
], ],
}, },
}, },
thresholds: { thresholds: {
http_req_failed: ['rate<0.05'], http_req_failed: ['rate<0.01'],
http_req_duration: ['p(95)<2000'], http_req_duration: ['p(95)<2000'],
works_list_shape_error_rate: ['rate<0.05'], dropped_iterations: ['count==0'],
works_list_shape_error_rate: ['rate<0.01'],
}, },
}, },
}; };

119
scripts/run-otelcol.mjs Normal file
View File

@@ -0,0 +1,119 @@
import {spawn} from 'node:child_process';
import {mkdirSync, writeFileSync} from 'node:fs';
import path from 'node:path';
const [, , rawMode = 'debug', ...args] = process.argv;
const mode = rawMode.trim();
const printConfigOnly = args.includes('--print-config');
const supportedModes = new Set(['debug', 'rider']);
if (!supportedModes.has(mode)) {
console.error('[otelcol] mode must be one of: debug, rider');
process.exit(1);
}
const otlpHttpEndpoint = readEnv('OTELCOL_OTLP_HTTP_ENDPOINT', '127.0.0.1:4318');
const otlpGrpcEndpoint = readEnv('OTELCOL_OTLP_GRPC_ENDPOINT', '127.0.0.1:4317');
const riderEndpoint = readEnv('RIDER_OTLP_GRPC_ENDPOINT', '127.0.0.1:17011');
const debugVerbosity = readEnv('OTELCOL_DEBUG_VERBOSITY', 'detailed');
const otelcolBin = readEnv('OTELCOL_BIN', 'otelcol-contrib');
const configText = buildConfig(mode);
const configDir = path.resolve('.codex-temp', 'otelcol');
const configPath = path.join(configDir, `genarrative-${mode}.yaml`);
mkdirSync(configDir, {recursive: true});
writeFileSync(configPath, configText, 'utf8');
console.log(`[otelcol] wrote ${configPath}`);
console.log(`[otelcol] receiving OTLP HTTP at http://${otlpHttpEndpoint}`);
console.log(`[otelcol] receiving OTLP gRPC at ${otlpGrpcEndpoint}`);
if (mode === 'rider') {
console.log(`[otelcol] forwarding traces/metrics/logs to Rider OTLP gRPC at ${riderEndpoint}`);
}
console.log(
'[otelcol] api-server env: GENARRATIVE_OTEL_ENABLED=true OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318'
);
if (printConfigOnly) {
console.log(configText);
process.exit(0);
}
const child = spawn(otelcolBin, ['--config', configPath], {
cwd: process.cwd(),
env: process.env,
stdio: 'inherit',
});
const stopChild = () => {
if (!child.killed) {
child.kill();
}
};
for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP']) {
process.on(signal, () => {
stopChild();
process.exit(130);
});
}
process.on('exit', stopChild);
child.on('error', (error) => {
console.error(`[otelcol] failed to start ${otelcolBin}: ${error.message}`);
console.error('[otelcol] install otelcol-contrib and make sure it is on PATH, or set OTELCOL_BIN.');
process.exit(1);
});
child.on('exit', (code, signal) => {
if (signal) {
console.error(`[otelcol] exited by signal: ${signal}`);
process.exit(1);
}
process.exit(code ?? 0);
});
function readEnv(key, fallback) {
const value = process.env[key]?.trim();
return value ? value : fallback;
}
function buildConfig(selectedMode) {
const exporters =
selectedMode === 'rider'
? ` otlp/rider:
endpoint: ${riderEndpoint}
tls:
insecure: true
debug:
verbosity: ${debugVerbosity}`
: ` debug:
verbosity: ${debugVerbosity}`;
const pipelineExporters = selectedMode === 'rider' ? '[otlp/rider, debug]' : '[debug]';
return `receivers:
otlp:
protocols:
grpc:
endpoint: ${otlpGrpcEndpoint}
http:
endpoint: ${otlpHttpEndpoint}
exporters:
${exporters}
service:
pipelines:
traces:
receivers: [otlp]
exporters: ${pipelineExporters}
metrics:
receivers: [otlp]
exporters: ${pipelineExporters}
logs:
receivers: [otlp]
exporters: ${pipelineExporters}
`;
}

186
server-rs/Cargo.lock generated
View File

@@ -105,6 +105,7 @@ dependencies = [
"module-square-hole", "module-square-hole",
"module-story", "module-story",
"module-visual-novel", "module-visual-novel",
"opentelemetry",
"platform-agent", "platform-agent",
"platform-auth", "platform-auth",
"platform-llm", "platform-llm",
@@ -118,6 +119,7 @@ dependencies = [
"shared-contracts", "shared-contracts",
"shared-kernel", "shared-kernel",
"shared-logging", "shared-logging",
"socket2 0.6.3",
"spacetime-client", "spacetime-client",
"time", "time",
"tokio", "tokio",
@@ -2070,6 +2072,90 @@ dependencies = [
"vcpkg", "vcpkg",
] ]
[[package]]
name = "opentelemetry"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b84bcd6ae87133e903af7ef497404dda70c60d0ea14895fc8a5e6722754fc2a0"
dependencies = [
"futures-core",
"futures-sink",
"js-sys",
"pin-project-lite",
"thiserror 2.0.18",
"tracing",
]
[[package]]
name = "opentelemetry-appender-tracing"
version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef6a1ac5ca3accf562b8c306fa8483c85f4390f768185ab775f242f7fe8fdcc2"
dependencies = [
"opentelemetry",
"tracing",
"tracing-core",
"tracing-opentelemetry",
"tracing-subscriber",
]
[[package]]
name = "opentelemetry-http"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7a6d09a73194e6b66df7c8f1b680f156d916a1a942abf2de06823dd02b7855d"
dependencies = [
"async-trait",
"bytes",
"http 1.4.0",
"opentelemetry",
"reqwest 0.12.28",
]
[[package]]
name = "opentelemetry-otlp"
version = "0.31.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f69cd6acbb9af919df949cd1ec9e5e7fdc2ef15d234b6b795aaa525cc02f71f"
dependencies = [
"http 1.4.0",
"opentelemetry",
"opentelemetry-http",
"opentelemetry-proto",
"opentelemetry_sdk",
"prost",
"reqwest 0.12.28",
"thiserror 2.0.18",
]
[[package]]
name = "opentelemetry-proto"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7175df06de5eaee9909d4805a3d07e28bb752c34cab57fa9cff549da596b30f"
dependencies = [
"opentelemetry",
"opentelemetry_sdk",
"prost",
"tonic",
"tonic-prost",
]
[[package]]
name = "opentelemetry_sdk"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e14ae4f5991976fd48df6d843de219ca6d31b01daaab2dad5af2badeded372bd"
dependencies = [
"futures-channel",
"futures-executor",
"futures-util",
"opentelemetry",
"percent-encoding",
"rand 0.9.4",
"thiserror 2.0.18",
]
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.12.5" version = "0.12.5"
@@ -2151,6 +2237,26 @@ dependencies = [
"indexmap 2.14.0", "indexmap 2.14.0",
] ]
[[package]]
name = "pin-project"
version = "1.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
version = "1.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "pin-project-lite" name = "pin-project-lite"
version = "0.2.17" version = "0.2.17"
@@ -2320,6 +2426,29 @@ dependencies = [
"thiserror 2.0.18", "thiserror 2.0.18",
] ]
[[package]]
name = "prost"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568"
dependencies = [
"bytes",
"prost-derive",
]
[[package]]
name = "prost-derive"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b"
dependencies = [
"anyhow",
"itertools",
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "protobuf" name = "protobuf"
version = "3.7.2" version = "3.7.2"
@@ -2622,6 +2751,7 @@ checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147"
dependencies = [ dependencies = [
"base64 0.22.1", "base64 0.22.1",
"bytes", "bytes",
"futures-channel",
"futures-core", "futures-core",
"futures-util", "futures-util",
"http 1.4.0", "http 1.4.0",
@@ -3036,6 +3166,12 @@ dependencies = [
name = "shared-logging" name = "shared-logging"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"opentelemetry",
"opentelemetry-appender-tracing",
"opentelemetry-otlp",
"opentelemetry_sdk",
"tracing",
"tracing-opentelemetry",
"tracing-subscriber", "tracing-subscriber",
] ]
@@ -3130,6 +3266,7 @@ dependencies = [
"module-square-hole", "module-square-hole",
"module-story", "module-story",
"module-visual-novel", "module-visual-novel",
"opentelemetry",
"serde", "serde",
"serde_json", "serde_json",
"shared-contracts", "shared-contracts",
@@ -3137,6 +3274,7 @@ dependencies = [
"spacetimedb-sdk", "spacetimedb-sdk",
"time", "time",
"tokio", "tokio",
"tracing",
] ]
[[package]] [[package]]
@@ -3807,6 +3945,38 @@ version = "1.1.1+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db"
[[package]]
name = "tonic"
version = "0.14.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef"
dependencies = [
"async-trait",
"base64 0.22.1",
"bytes",
"http 1.4.0",
"http-body 1.0.1",
"http-body-util",
"percent-encoding",
"pin-project",
"sync_wrapper 1.0.2",
"tokio-stream",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tonic-prost"
version = "0.14.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50849f68853be452acf590cde0b146665b8d507b3b8af17261df47e02c209ea0"
dependencies = [
"bytes",
"prost",
"tonic",
]
[[package]] [[package]]
name = "tower" name = "tower"
version = "0.5.3" version = "0.5.3"
@@ -3898,6 +4068,22 @@ dependencies = [
"tracing-core", "tracing-core",
] ]
[[package]]
name = "tracing-opentelemetry"
version = "0.32.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ac28f2d093c6c477eaa76b23525478f38de514fa9aeb1285738d4b97a9552fc"
dependencies = [
"js-sys",
"opentelemetry",
"smallvec",
"tracing",
"tracing-core",
"tracing-log",
"tracing-subscriber",
"web-time",
]
[[package]] [[package]]
name = "tracing-subscriber" name = "tracing-subscriber"
version = "0.3.23" version = "0.3.23"

View File

@@ -100,6 +100,7 @@ serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"
serde_urlencoded = "0.7" serde_urlencoded = "0.7"
sha2 = "0.10" sha2 = "0.10"
socket2 = "0.6"
spacetimedb = "2.2.0" spacetimedb = "2.2.0"
spacetimedb-sdk = "2.2.0" spacetimedb-sdk = "2.2.0"
spacetimedb-lib = { version = "2.2.0", default-features = false } spacetimedb-lib = { version = "2.2.0", default-features = false }
@@ -110,6 +111,11 @@ tokio-tungstenite = "0.27"
tower = "0.5" tower = "0.5"
tower-http = "0.6" tower-http = "0.6"
tracing = "0.1" tracing = "0.1"
opentelemetry = "0.31"
opentelemetry-appender-tracing = { version = "0.31", default-features = false, features = ["experimental_use_tracing_span_context"] }
opentelemetry-otlp = { version = "0.31", default-features = false, features = ["http-proto", "reqwest-blocking-client", "trace", "metrics", "logs"] }
opentelemetry_sdk = { version = "0.31", default-features = false, features = ["trace", "metrics", "logs"] }
tracing-opentelemetry = { version = "0.32", default-features = false }
tracing-subscriber = "0.3" tracing-subscriber = "0.3"
url = "2" url = "2"
urlencoding = "2" urlencoding = "2"

View File

@@ -43,6 +43,7 @@ sha2 = { workspace = true }
shared-contracts = { workspace = true, features = ["oss-contracts"] } shared-contracts = { workspace = true, features = ["oss-contracts"] }
shared-kernel = { workspace = true } shared-kernel = { workspace = true }
shared-logging = { workspace = true } shared-logging = { workspace = true }
socket2 = { workspace = true }
spacetime-client = { workspace = true } spacetime-client = { workspace = true }
tokio = { workspace = true, features = ["macros", "rt-multi-thread", "net", "time"] } tokio = { workspace = true, features = ["macros", "rt-multi-thread", "net", "time"] }
tokio-stream = { workspace = true } tokio-stream = { workspace = true }
@@ -50,6 +51,7 @@ futures-util = { workspace = true }
time = { workspace = true, features = ["formatting"] } time = { workspace = true, features = ["formatting"] }
tower-http = { workspace = true, features = ["trace"] } tower-http = { workspace = true, features = ["trace"] }
tracing = { workspace = true } tracing = { workspace = true }
opentelemetry = { workspace = true }
url = { workspace = true } url = { workspace = true }
urlencoding = { workspace = true } urlencoding = { workspace = true }
uuid = { workspace = true, features = ["v4"] } uuid = { workspace = true, features = ["v4"] }

View File

@@ -11,7 +11,7 @@ use tower_http::{
classify::ServerErrorsFailureClass, classify::ServerErrorsFailureClass,
trace::{DefaultOnRequest, TraceLayer}, trace::{DefaultOnRequest, TraceLayer},
}; };
use tracing::{Level, Span, error, info, info_span, warn}; use tracing::{Level, Span, error, info_span};
use crate::{ use crate::{
auth::{AuthenticatedAccessToken, require_bearer_auth}, auth::{AuthenticatedAccessToken, require_bearer_auth},
@@ -22,6 +22,7 @@ use crate::{
response_headers::propagate_request_id_header, response_headers::propagate_request_id_header,
runtime_inventory::get_runtime_inventory_state, runtime_inventory::get_runtime_inventory_state,
state::AppState, state::AppState,
telemetry::record_http_observability,
tracking::record_route_tracking_event_after_success, tracking::record_route_tracking_event_after_success,
vector_engine_audio_generation::{ vector_engine_audio_generation::{
create_background_music_task, create_sound_effect_task, create_background_music_task, create_sound_effect_task,
@@ -42,8 +43,6 @@ use crate::{
// 统一由这里构造 Axum 路由树,后续再逐项挂接中间件与业务路由。 // 统一由这里构造 Axum 路由树,后续再逐项挂接中间件与业务路由。
pub fn build_router(state: AppState) -> Router { pub fn build_router(state: AppState) -> Router {
let slow_request_threshold_ms = state.config.slow_request_threshold_ms;
Router::new() Router::new()
.merge(modules::admin::router(state.clone())) .merge(modules::admin::router(state.clone()))
.merge(modules::health::router(state.clone())) .merge(modules::health::router(state.clone()))
@@ -86,47 +85,55 @@ pub fn build_router(state: AppState) -> Router {
state.clone(), state.clone(),
record_api_tracking_after_success, record_api_tracking_after_success,
)) ))
// HTTP 指标与请求完成日志放在 tracing span 内侧,日志事件可以继承当前 trace/span context。
.layer(middleware::from_fn_with_state(
state.clone(),
record_http_observability,
))
// 当前阶段先统一挂接 HTTP tracing后续 request_id、响应头与错误中间件继续在这里扩展。 // 当前阶段先统一挂接 HTTP tracing后续 request_id、响应头与错误中间件继续在这里扩展。
.layer( .layer(
TraceLayer::new_for_http() TraceLayer::new_for_http()
.make_span_with(|request: &Request<Body>| { .make_span_with(|request: &Request<Body>| {
let request_id = let request_id =
resolve_request_id(request).unwrap_or_else(|| "unknown".to_string()); resolve_request_id(request).unwrap_or_else(|| "unknown".to_string());
let route = crate::telemetry::observability_route(request.uri().path());
let scheme = crate::telemetry::resolve_request_scheme(request.headers());
let span_name = format!("{} {}", request.method(), route);
info_span!( info_span!(
"http.request", "http.request",
otel.kind = "server",
otel.name = %span_name,
otel.status_code = tracing::field::Empty,
http.response.status_code = tracing::field::Empty,
method = %request.method(), method = %request.method(),
uri = %request.uri(), http.request.method = %request.method(),
http.route = %route,
url.scheme = %scheme,
url.path = %request.uri().path(),
request_id = %request_id, request_id = %request_id,
status = tracing::field::Empty,
latency_ms = tracing::field::Empty,
) )
}) })
.on_request(DefaultOnRequest::new().level(Level::INFO)) .on_request(DefaultOnRequest::new().level(Level::INFO))
.on_response( .on_response(
move |response: &axum::response::Response, |response: &axum::response::Response,
latency: std::time::Duration, latency: std::time::Duration,
span: &Span| { span: &Span| {
let latency_ms = latency.as_millis().min(u64::MAX as u128) as u64; let latency_ms = latency.as_millis().min(u64::MAX as u128) as u64;
let status = response.status().as_u16(); let status = response.status().as_u16();
let slow_request = latency_ms >= slow_request_threshold_ms;
span.record("status", status); span.record("status", status);
span.record("http.response.status_code", status);
span.record(
"otel.status_code",
if response.status().is_server_error() {
"ERROR"
} else {
"OK"
},
);
span.record("latency_ms", latency_ms); span.record("latency_ms", latency_ms);
if slow_request {
warn!(
parent: span,
status,
latency_ms,
slow_request = true,
"http request completed slowly"
);
} else {
info!(
parent: span,
status,
latency_ms,
slow_request = false,
"http request completed"
);
}
}, },
) )
.on_failure( .on_failure(

View File

@@ -752,10 +752,14 @@ mod tests {
}; };
use hmac::{Hmac, Mac}; use hmac::{Hmac, Mac};
use http_body_util::BodyExt; use http_body_util::BodyExt;
use platform_auth::{
AccessTokenClaims, AccessTokenClaimsInput, AuthProvider, BindingStatus, sign_access_token,
};
use reqwest::{Method, multipart}; use reqwest::{Method, multipart};
use serde_json::{Value, json}; use serde_json::{Value, json};
use sha2::{Digest, Sha256}; use sha2::{Digest, Sha256};
use shared_kernel::new_uuid_simple_string; use shared_kernel::new_uuid_simple_string;
use time::OffsetDateTime;
use tower::ServiceExt; use tower::ServiceExt;
use crate::{app::build_router, config::AppConfig, state::AppState}; use crate::{app::build_router, config::AppConfig, state::AppState};
@@ -873,13 +877,17 @@ mod tests {
..AppConfig::default() ..AppConfig::default()
}; };
let app = build_router(AppState::new(config).expect("state should build")); let state = AppState::new(config).expect("state should build");
let token =
seed_authenticated_token(&state, "13800138120", "sess_assets_direct_upload").await;
let app = build_router(state);
let response = app let response = app
.oneshot( .oneshot(
Request::builder() Request::builder()
.method("POST") .method("POST")
.uri("/api/assets/direct-upload-tickets") .uri("/api/assets/direct-upload-tickets")
.header("authorization", format!("Bearer {token}"))
.header("content-type", "application/json") .header("content-type", "application/json")
.header("x-request-id", "req-oss-ticket") .header("x-request-id", "req-oss-ticket")
.header("x-genarrative-response-envelope", "1") .header("x-genarrative-response-envelope", "1")
@@ -1693,6 +1701,33 @@ mod tests {
Ok(fields) Ok(fields)
} }
async fn seed_authenticated_token(
state: &AppState,
phone_number: &str,
session_seed: &str,
) -> String {
let user = state
.seed_test_phone_user_with_password(phone_number, "secret123")
.await;
let claims = AccessTokenClaims::from_input(
AccessTokenClaimsInput {
user_id: user.id.clone(),
session_id: state.seed_test_refresh_session_for_user(&user, session_seed),
provider: AuthProvider::Password,
roles: vec!["user".to_string()],
token_version: user.token_version,
phone_verified: true,
binding_status: BindingStatus::Active,
display_name: Some(user.display_name.clone()),
},
state.auth_jwt_config(),
OffsetDateTime::now_utc(),
)
.expect("claims should build");
sign_access_token(&claims, state.auth_jwt_config()).expect("token should sign")
}
fn build_object_url( fn build_object_url(
config: &AppConfig, config: &AppConfig,
object_key: &str, object_key: &str,

View File

@@ -20,7 +20,10 @@ pub(crate) const DEFAULT_VECTOR_ENGINE_IMAGE_REQUEST_TIMEOUT_MS: u64 = 1_000_000
pub struct AppConfig { pub struct AppConfig {
pub bind_host: String, pub bind_host: String,
pub bind_port: u16, pub bind_port: u16,
pub listen_backlog: i32,
pub worker_threads: Option<usize>,
pub log_filter: String, pub log_filter: String,
pub otel_enabled: bool,
pub admin_username: Option<String>, pub admin_username: Option<String>,
pub admin_password: Option<String>, pub admin_password: Option<String>,
pub admin_token_ttl_seconds: u64, pub admin_token_ttl_seconds: u64,
@@ -147,7 +150,10 @@ impl Default for AppConfig {
Self { Self {
bind_host: "127.0.0.1".to_string(), bind_host: "127.0.0.1".to_string(),
bind_port: 3000, bind_port: 3000,
listen_backlog: 1024,
worker_threads: None,
log_filter: "info,tower_http=info".to_string(), log_filter: "info,tower_http=info".to_string(),
otel_enabled: false,
admin_username: None, admin_username: None,
admin_password: None, admin_password: None,
admin_token_ttl_seconds: 4 * 60 * 60, admin_token_ttl_seconds: 4 * 60 * 60,
@@ -301,6 +307,17 @@ impl AppConfig {
{ {
config.log_filter = log_filter; config.log_filter = log_filter;
} }
if let Some(listen_backlog) =
read_first_positive_i32_env(&["GENARRATIVE_API_LISTEN_BACKLOG"])
{
config.listen_backlog = listen_backlog;
}
if let Some(worker_threads) = read_first_usize_env(&["GENARRATIVE_API_WORKER_THREADS"]) {
config.worker_threads = Some(worker_threads);
}
if let Some(otel_enabled) = read_first_bool_env(&["GENARRATIVE_OTEL_ENABLED"]) {
config.otel_enabled = otel_enabled;
}
config.admin_username = read_first_non_empty_env(&["GENARRATIVE_ADMIN_USERNAME"]); config.admin_username = read_first_non_empty_env(&["GENARRATIVE_ADMIN_USERNAME"]);
config.admin_password = read_first_non_empty_env(&["GENARRATIVE_ADMIN_PASSWORD"]); config.admin_password = read_first_non_empty_env(&["GENARRATIVE_ADMIN_PASSWORD"]);
@@ -881,6 +898,14 @@ fn read_first_positive_u32_env(keys: &[&str]) -> Option<u32> {
}) })
} }
fn read_first_positive_i32_env(keys: &[&str]) -> Option<i32> {
keys.iter().find_map(|key| {
env::var(key)
.ok()
.and_then(|value| parse_positive_i32(&value))
})
}
fn read_first_positive_u64_env(keys: &[&str]) -> Option<u64> { fn read_first_positive_u64_env(keys: &[&str]) -> Option<u64> {
keys.iter().find_map(|key| { keys.iter().find_map(|key| {
env::var(key) env::var(key)
@@ -971,6 +996,15 @@ fn parse_positive_u32(raw: &str) -> Option<u32> {
Some(value) Some(value)
} }
fn parse_positive_i32(raw: &str) -> Option<i32> {
let value = raw.trim().parse::<i32>().ok()?;
if value <= 0 {
return None;
}
Some(value)
}
fn parse_u32(raw: &str) -> Option<u32> { fn parse_u32(raw: &str) -> Option<u32> {
raw.trim().parse::<u32>().ok() raw.trim().parse::<u32>().ok()
} }
@@ -1151,6 +1185,34 @@ mod tests {
} }
} }
#[test]
fn from_env_reads_api_runtime_performance_settings() {
let _guard = ENV_LOCK
.get_or_init(|| Mutex::new(()))
.lock()
.expect("env lock should not poison");
unsafe {
std::env::remove_var("GENARRATIVE_API_LISTEN_BACKLOG");
std::env::remove_var("GENARRATIVE_API_WORKER_THREADS");
std::env::remove_var("GENARRATIVE_OTEL_ENABLED");
std::env::set_var("GENARRATIVE_API_LISTEN_BACKLOG", "2048");
std::env::set_var("GENARRATIVE_API_WORKER_THREADS", "6");
std::env::set_var("GENARRATIVE_OTEL_ENABLED", "true");
}
let config = AppConfig::from_env();
assert_eq!(config.listen_backlog, 2048);
assert_eq!(config.worker_threads, Some(6));
assert!(config.otel_enabled);
unsafe {
std::env::remove_var("GENARRATIVE_API_LISTEN_BACKLOG");
std::env::remove_var("GENARRATIVE_API_WORKER_THREADS");
std::env::remove_var("GENARRATIVE_OTEL_ENABLED");
}
}
#[test] #[test]
fn from_env_reads_wechat_pay_settings() { fn from_env_reads_wechat_pay_settings() {
let _guard = ENV_LOCK let _guard = ENV_LOCK

View File

@@ -75,6 +75,7 @@ mod square_hole_agent_turn;
mod state; mod state;
mod story_battles; mod story_battles;
mod story_sessions; mod story_sessions;
mod telemetry;
mod tracking; mod tracking;
mod vector_engine_audio_generation; mod vector_engine_audio_generation;
mod visual_novel; mod visual_novel;
@@ -85,8 +86,15 @@ mod wechat_provider;
mod work_author; mod work_author;
mod work_play_tracking; mod work_play_tracking;
use shared_logging::init_tracing; use shared_logging::{OtelConfig, init_tracing};
use std::{collections::HashSet, env, fs, io, panic, thread, time::Duration}; use socket2::{Domain, Protocol, Socket, Type};
use std::{
collections::HashSet,
env, fs, io,
net::{SocketAddr, TcpListener as StdTcpListener},
panic, thread,
time::Duration,
};
use tokio::net::TcpListener; use tokio::net::TcpListener;
use tokio::runtime::Builder as TokioRuntimeBuilder; use tokio::runtime::Builder as TokioRuntimeBuilder;
use tokio::time::timeout; use tokio::time::timeout;
@@ -103,12 +111,18 @@ fn main() -> Result<(), io::Error> {
.name("api-server-bootstrap".to_string()) .name("api-server-bootstrap".to_string())
.stack_size(API_SERVER_STARTUP_STACK_SIZE_BYTES) .stack_size(API_SERVER_STARTUP_STACK_SIZE_BYTES)
.spawn(|| { .spawn(|| {
TokioRuntimeBuilder::new_multi_thread() load_local_env_files();
let config = AppConfig::from_env();
let mut runtime_builder = TokioRuntimeBuilder::new_multi_thread();
runtime_builder
.enable_all() .enable_all()
.thread_name("api-server-worker") .thread_name("api-server-worker")
.thread_stack_size(API_SERVER_STARTUP_STACK_SIZE_BYTES) .thread_stack_size(API_SERVER_STARTUP_STACK_SIZE_BYTES);
.build()? if let Some(worker_threads) = config.worker_threads {
.block_on(run_server()) runtime_builder.worker_threads(worker_threads);
}
runtime_builder.build()?.block_on(run_server(config))
})?; })?;
match server_thread.join() { match server_thread.join() {
@@ -117,28 +131,49 @@ fn main() -> Result<(), io::Error> {
} }
} }
async fn run_server() -> Result<(), io::Error> { async fn run_server(config: AppConfig) -> Result<(), io::Error> {
// 运行本地开发与联调时,优先从仓库根目录加载本地变量。 init_tracing(
// 只尊重外层 shell 先注入的变量;后续本地文件需要能覆盖前序本地文件。 &config.log_filter,
load_local_env_files(); OtelConfig {
enabled: config.otel_enabled,
// 统一先从配置对象读取监听地址,避免后续把环境变量读取散落到入口和路由层。 },
let config = AppConfig::from_env(); )?;
init_tracing(&config.log_filter)?;
let bind_address = config.bind_socket_addr(); let bind_address = config.bind_socket_addr();
let listener = TcpListener::bind(bind_address).await?; let listen_backlog = config.listen_backlog;
let worker_threads = config.worker_threads;
let otel_enabled = config.otel_enabled;
let listener = build_tcp_listener(bind_address, listen_backlog)?;
let state = restore_app_state_for_startup(config) let state = restore_app_state_for_startup(config)
.await .await
.map_err(|error| std::io::Error::other(format!("初始化应用状态失败:{error}")))?; .map_err(|error| std::io::Error::other(format!("初始化应用状态失败:{error}")))?;
let router = build_router(state); let router = build_router(state);
info!(%bind_address, "api-server 已完成 tracing 初始化并开始监听"); info!(
%bind_address,
listen_backlog,
worker_threads = worker_threads.unwrap_or(0),
otel_enabled,
"api-server 已完成 tracing 初始化并开始监听"
);
axum::serve(listener, router).await axum::serve(listener, router).await
} }
fn build_tcp_listener(
bind_address: SocketAddr,
listen_backlog: i32,
) -> Result<TcpListener, io::Error> {
let domain = Domain::for_address(bind_address);
let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))?;
socket.set_reuse_address(true)?;
socket.set_nonblocking(true)?;
socket.bind(&bind_address.into())?;
socket.listen(listen_backlog)?;
TcpListener::from_std(StdTcpListener::from(socket))
}
async fn restore_app_state_for_startup( async fn restore_app_state_for_startup(
config: AppConfig, config: AppConfig,
) -> Result<AppState, state::AppStateInitError> { ) -> Result<AppState, state::AppStateInitError> {

View File

@@ -0,0 +1,182 @@
use axum::{
body::Body,
extract::State,
http::{HeaderMap, Request, Response},
middleware::Next,
};
use opentelemetry::{KeyValue, global, metrics::Counter};
use tracing::{info, warn};
use crate::{request_context::resolve_request_id, state::AppState};
// 集中维护 api-server HTTP 观测,避免在 handler 中散落高基数字段或重复创建 instrument。
pub async fn record_http_observability(
State(state): State<AppState>,
request: Request<Body>,
next: Next,
) -> Response<Body> {
let method = request.method().as_str().to_string();
let route = observability_route(request.uri().path());
let scheme = resolve_request_scheme(request.headers());
let path = request.uri().path().to_string();
let request_id = resolve_request_id(&request).unwrap_or_else(|| "unknown".to_string());
let base_labels = http_base_labels(method.clone(), route.clone());
let metrics = http_metrics();
metrics.in_flight.add(1, &base_labels);
let started_at = std::time::Instant::now();
let response = next.run(request).await;
let status = response.status().as_u16();
let status_class = status_class(status);
let latency_ms = started_at.elapsed().as_millis().min(u64::MAX as u128) as u64;
let slow_request = latency_ms >= state.config.slow_request_threshold_ms;
let labels = http_response_labels(base_labels, status);
metrics.requests.add(1, &labels);
metrics
.duration
.record(started_at.elapsed().as_secs_f64(), &labels);
metrics.in_flight.add(-1, &labels[..2]);
if slow_request {
warn!(
request_id = %request_id,
http.request.method = %method,
http.route = %route,
url.scheme = %scheme,
url.path = %path,
http.response.status_code = status,
status,
status_class,
latency_ms,
slow_request = true,
"http request completed slowly"
);
} else {
info!(
request_id = %request_id,
http.request.method = %method,
http.route = %route,
url.scheme = %scheme,
url.path = %path,
http.response.status_code = status,
status,
status_class,
latency_ms,
slow_request = false,
"http request completed"
);
}
response
}
struct HttpMetrics {
requests: Counter<u64>,
in_flight: opentelemetry::metrics::UpDownCounter<i64>,
duration: opentelemetry::metrics::Histogram<f64>,
}
fn http_metrics() -> &'static HttpMetrics {
static METRICS: std::sync::OnceLock<HttpMetrics> = std::sync::OnceLock::new();
METRICS.get_or_init(|| {
let meter = global::meter("genarrative-api");
HttpMetrics {
requests: meter
.u64_counter("genarrative.http.server.requests")
.with_description("HTTP request count grouped by route and status class")
.build(),
in_flight: meter
.i64_up_down_counter("http.server.active_requests")
.with_unit("{request}")
.with_description("Number of active HTTP server requests")
.build(),
duration: meter
.f64_histogram("http.server.request.duration")
.with_unit("s")
.with_description("Duration of HTTP server requests")
.build(),
}
})
}
fn http_base_labels(method: String, route: String) -> Vec<KeyValue> {
vec![
KeyValue::new("http.request.method", method),
KeyValue::new("http.route", route),
]
}
fn http_response_labels(mut labels: Vec<KeyValue>, status: u16) -> Vec<KeyValue> {
labels.push(KeyValue::new("status_class", status_class(status)));
labels
}
fn status_class(status: u16) -> &'static str {
match status {
100..=199 => "1xx",
200..=299 => "2xx",
300..=399 => "3xx",
400..=499 => "4xx",
500..=599 => "5xx",
_ => "unknown",
}
}
pub(crate) fn observability_route(path: &str) -> String {
if path.starts_with("/api/runtime/puzzle/gallery") {
"/api/runtime/puzzle/gallery".to_string()
} else if path.starts_with("/api/runtime/custom-world-gallery") {
"/api/runtime/custom-world-gallery".to_string()
} else if path.starts_with("/admin/api/") {
"/admin/api/*".to_string()
} else if path.starts_with("/api/") {
"/api/*".to_string()
} else {
"other".to_string()
}
}
pub(crate) fn resolve_request_scheme(headers: &HeaderMap) -> String {
headers
.get("x-forwarded-proto")
.and_then(|value| value.to_str().ok())
.and_then(|value| value.split(',').next())
.map(str::trim)
.filter(|value| !value.is_empty())
.unwrap_or("http")
.to_string()
}
#[cfg(test)]
mod tests {
use axum::http::{HeaderMap, HeaderValue};
use super::{observability_route, resolve_request_scheme};
#[test]
fn observability_route_keeps_metrics_labels_low_cardinality() {
assert_eq!(
observability_route("/api/runtime/puzzle/gallery?cursor=abc"),
"/api/runtime/puzzle/gallery"
);
assert_eq!(
observability_route("/api/runtime/puzzle/runs/run-123/history"),
"/api/*"
);
assert_eq!(
observability_route("/admin/api/debug/http"),
"/admin/api/*"
);
}
#[test]
fn resolve_request_scheme_uses_forwarded_proto_first_value() {
let mut headers = HeaderMap::new();
headers.insert(
"x-forwarded-proto",
HeaderValue::from_static("https, http"),
);
assert_eq!(resolve_request_scheme(&headers), "https");
}
}

View File

@@ -5,4 +5,10 @@ version.workspace = true
license.workspace = true license.workspace = true
[dependencies] [dependencies]
tracing-subscriber = { workspace = true, features = ["env-filter", "fmt"] } opentelemetry = { workspace = true }
opentelemetry-otlp = { workspace = true }
opentelemetry-appender-tracing = { workspace = true }
opentelemetry_sdk = { workspace = true }
tracing = { workspace = true }
tracing-opentelemetry = { workspace = true }
tracing-subscriber = { workspace = true, features = ["env-filter", "fmt", "registry"] }

View File

@@ -1,6 +1,23 @@
use std::io; use std::io;
use tracing_subscriber::{EnvFilter, fmt}; 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,
};
use tracing::warn;
use tracing_subscriber::{
EnvFilter, Layer, filter::LevelFilter, fmt, layer::SubscriberExt, util::SubscriberInitExt,
};
#[derive(Clone, Copy, Debug, Default)]
pub struct OtelConfig {
pub enabled: bool,
}
// 统一解析工作区日志过滤器,优先环境变量,其次回落到调用方传入的默认值。 // 统一解析工作区日志过滤器,优先环境变量,其次回落到调用方传入的默认值。
pub fn resolve_env_filter(default_filter: &str) -> EnvFilter { pub fn resolve_env_filter(default_filter: &str) -> EnvFilter {
@@ -10,14 +27,196 @@ pub fn resolve_env_filter(default_filter: &str) -> EnvFilter {
} }
// 统一初始化 tracing subscriber避免各入口重复散落相同配置。 // 统一初始化 tracing subscriber避免各入口重复散落相同配置。
pub fn init_tracing(default_filter: &str) -> Result<(), io::Error> { pub fn init_tracing(default_filter: &str, otel_config: OtelConfig) -> Result<(), io::Error> {
let env_filter = resolve_env_filter(default_filter); let env_filter = resolve_env_filter(default_filter);
let fmt_layer = fmt::layer().with_target(true).with_ansi(false).compact();
fmt() if !otel_config.enabled {
.with_env_filter(env_filter) return tracing_subscriber::registry()
.with_target(true) .with(env_filter)
.with_ansi(false) .with(fmt_layer)
.compact() .try_init()
.map_err(|error| io::Error::other(format!("初始化 tracing subscriber 失败:{error}")));
}
let Some(otel) = build_otel_pipeline() else {
return tracing_subscriber::registry()
.with(env_filter)
.with(fmt_layer)
.try_init()
.map_err(|error| io::Error::other(format!("初始化 tracing subscriber 失败:{error}")));
};
tracing_subscriber::registry()
.with(env_filter)
.with(fmt_layer)
.with(
tracing_opentelemetry::layer()
.with_tracer(otel.tracer_provider.tracer("genarrative-api")),
)
.with(
OpenTelemetryTracingBridge::new(&otel.logger_provider).with_filter(LevelFilter::INFO),
)
.try_init() .try_init()
.map_err(|error| io::Error::other(format!("初始化 tracing subscriber 失败:{error}"))) .map_err(|error| io::Error::other(format!("初始化 tracing subscriber 失败:{error}")))
} }
struct OtelPipeline {
tracer_provider: SdkTracerProvider,
_meter_provider: SdkMeterProvider,
logger_provider: SdkLoggerProvider,
}
fn build_otel_pipeline() -> Option<OtelPipeline> {
let resource = Resource::builder()
.with_service_name(read_env_or_default("OTEL_SERVICE_NAME", "genarrative-api"))
.with_attribute(KeyValue::new("service.namespace", "genarrative"))
.build();
let span_exporter = match opentelemetry_otlp::SpanExporter::builder()
.with_http()
.with_endpoint(resolve_otlp_http_signal_endpoint(
"OTEL_EXPORTER_OTLP_TRACES_ENDPOINT",
"/v1/traces",
))
.build()
{
Ok(exporter) => exporter,
Err(error) => {
warn!(%error, "OpenTelemetry span exporter 初始化失败,已回退为本地日志");
return None;
}
};
let metric_exporter = match opentelemetry_otlp::MetricExporter::builder()
.with_http()
.with_endpoint(resolve_otlp_http_signal_endpoint(
"OTEL_EXPORTER_OTLP_METRICS_ENDPOINT",
"/v1/metrics",
))
.build()
{
Ok(exporter) => exporter,
Err(error) => {
warn!(%error, "OpenTelemetry metric exporter 初始化失败,已回退为本地日志");
return None;
}
};
let log_exporter = match opentelemetry_otlp::LogExporter::builder()
.with_http()
.with_endpoint(resolve_otlp_http_signal_endpoint(
"OTEL_EXPORTER_OTLP_LOGS_ENDPOINT",
"/v1/logs",
))
.build()
{
Ok(exporter) => exporter,
Err(error) => {
warn!(%error, "OpenTelemetry log exporter 初始化失败,已回退为本地日志");
return None;
}
};
let tracer_provider = SdkTracerProvider::builder()
.with_resource(resource.clone())
.with_batch_exporter(span_exporter)
.build();
let meter_provider = SdkMeterProvider::builder()
.with_resource(resource)
.with_periodic_exporter(metric_exporter)
.build();
let logger_provider = SdkLoggerProvider::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())
.with_batch_exporter(log_exporter)
.build();
global::set_tracer_provider(tracer_provider.clone());
global::set_meter_provider(meter_provider.clone());
Some(OtelPipeline {
tracer_provider,
_meter_provider: meter_provider,
logger_provider,
})
}
fn read_env_or_default(key: &str, default_value: &str) -> String {
std::env::var(key)
.ok()
.filter(|value| !value.trim().is_empty())
.unwrap_or_else(|| default_value.to_string())
}
fn resolve_otlp_http_signal_endpoint(signal_key: &str, signal_path: &str) -> String {
if let Ok(value) = std::env::var(signal_key)
&& !value.trim().is_empty()
{
return value;
}
append_otlp_signal_path(
&read_env_or_default("OTEL_EXPORTER_OTLP_ENDPOINT", "http://127.0.0.1:4318"),
signal_path,
)
}
fn append_otlp_signal_path(base_endpoint: &str, signal_path: &str) -> String {
let base_endpoint = base_endpoint.trim_end_matches('/');
let signal_path = signal_path.trim_start_matches('/');
format!("{base_endpoint}/{signal_path}")
}
#[cfg(test)]
mod tests {
use std::sync::{Mutex, OnceLock};
use super::resolve_otlp_http_signal_endpoint;
const OTEL_ENDPOINT_ENV_KEYS: [&str; 4] = [
"OTEL_EXPORTER_OTLP_ENDPOINT",
"OTEL_EXPORTER_OTLP_TRACES_ENDPOINT",
"OTEL_EXPORTER_OTLP_METRICS_ENDPOINT",
"OTEL_EXPORTER_OTLP_LOGS_ENDPOINT",
];
fn env_lock() -> std::sync::MutexGuard<'static, ()> {
static LOCK: OnceLock<Mutex<()>> = OnceLock::new();
LOCK.get_or_init(|| Mutex::new(())).lock().unwrap()
}
fn clear_otel_endpoint_env() {
unsafe {
for key in OTEL_ENDPOINT_ENV_KEYS {
std::env::remove_var(key);
}
}
}
#[test]
fn generic_otlp_http_endpoint_expands_to_signal_paths() {
let _guard = env_lock();
clear_otel_endpoint_env();
unsafe {
std::env::set_var("OTEL_EXPORTER_OTLP_ENDPOINT", "http://127.0.0.1:4318");
}
assert_eq!(
resolve_otlp_http_signal_endpoint("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", "/v1/traces"),
"http://127.0.0.1:4318/v1/traces"
);
assert_eq!(
resolve_otlp_http_signal_endpoint("OTEL_EXPORTER_OTLP_METRICS_ENDPOINT", "/v1/metrics"),
"http://127.0.0.1:4318/v1/metrics"
);
assert_eq!(
resolve_otlp_http_signal_endpoint("OTEL_EXPORTER_OTLP_LOGS_ENDPOINT", "/v1/logs"),
"http://127.0.0.1:4318/v1/logs"
);
clear_otel_endpoint_env();
}
}

View File

@@ -27,3 +27,5 @@ shared-kernel = { workspace = true }
spacetimedb-sdk = { workspace = true } spacetimedb-sdk = { workspace = true }
time = { workspace = true } time = { workspace = true }
tokio = { workspace = true, features = ["rt", "sync", "time"] } tokio = { workspace = true, features = ["rt", "sync", "time"] }
opentelemetry = { workspace = true }
tracing = { workspace = true }

View File

@@ -8,7 +8,7 @@ impl SpacetimeClient {
) -> Result<AiTaskMutationRecord, SpacetimeClientError> { ) -> Result<AiTaskMutationRecord, SpacetimeClientError> {
let procedure_input = input.into(); let procedure_input = input.into();
self.call_after_connect(move |connection, sender| { self.call_after_connect("create_ai_task_and_return", move |connection, sender| {
connection.procedures().create_ai_task_and_return_then( connection.procedures().create_ai_task_and_return_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -28,7 +28,7 @@ impl SpacetimeClient {
) -> Result<(), SpacetimeClientError> { ) -> Result<(), SpacetimeClientError> {
let reducer_input = input.into(); let reducer_input = input.into();
self.call_reducer_after_connect(move |connection, sender| { self.call_reducer_after_connect("start_ai_task", move |connection, sender| {
let callback_sender = sender.clone(); let callback_sender = sender.clone();
if let Err(error) = if let Err(error) =
connection connection
@@ -52,7 +52,7 @@ impl SpacetimeClient {
) -> Result<(), SpacetimeClientError> { ) -> Result<(), SpacetimeClientError> {
let reducer_input = input.into(); let reducer_input = input.into();
self.call_reducer_after_connect(move |connection, sender| { self.call_reducer_after_connect("start_ai_task_stage", move |connection, sender| {
let callback_sender = sender.clone(); let callback_sender = sender.clone();
if let Err(error) = if let Err(error) =
connection connection
@@ -76,16 +76,19 @@ impl SpacetimeClient {
) -> Result<AiTaskMutationRecord, SpacetimeClientError> { ) -> Result<AiTaskMutationRecord, SpacetimeClientError> {
let procedure_input = input.into(); let procedure_input = input.into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "append_ai_text_chunk_and_return",
.procedures() move |connection, sender| {
.append_ai_text_chunk_and_return_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .append_ai_text_chunk_and_return_then(procedure_input, move |_, result| {
.and_then(map_ai_task_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_ai_task_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -95,7 +98,7 @@ impl SpacetimeClient {
) -> Result<AiTaskMutationRecord, SpacetimeClientError> { ) -> Result<AiTaskMutationRecord, SpacetimeClientError> {
let procedure_input = input.into(); let procedure_input = input.into();
self.call_after_connect(move |connection, sender| { self.call_after_connect("complete_ai_stage_and_return", move |connection, sender| {
connection.procedures().complete_ai_stage_and_return_then( connection.procedures().complete_ai_stage_and_return_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -115,16 +118,22 @@ impl SpacetimeClient {
) -> Result<AiTaskMutationRecord, SpacetimeClientError> { ) -> Result<AiTaskMutationRecord, SpacetimeClientError> {
let procedure_input = input.into(); let procedure_input = input.into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "attach_ai_result_reference_and_return",
.procedures() move |connection, sender| {
.attach_ai_result_reference_and_return_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .attach_ai_result_reference_and_return_then(
.and_then(map_ai_task_procedure_result); procedure_input,
send_once(&sender, mapped); move |_, result| {
}); let mapped = result
}) .map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_ai_task_procedure_result);
send_once(&sender, mapped);
},
);
},
)
.await .await
} }
@@ -134,7 +143,7 @@ impl SpacetimeClient {
) -> Result<AiTaskMutationRecord, SpacetimeClientError> { ) -> Result<AiTaskMutationRecord, SpacetimeClientError> {
let procedure_input = input.into(); let procedure_input = input.into();
self.call_after_connect(move |connection, sender| { self.call_after_connect("complete_ai_task_and_return", move |connection, sender| {
connection.procedures().complete_ai_task_and_return_then( connection.procedures().complete_ai_task_and_return_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -154,7 +163,7 @@ impl SpacetimeClient {
) -> Result<AiTaskMutationRecord, SpacetimeClientError> { ) -> Result<AiTaskMutationRecord, SpacetimeClientError> {
let procedure_input = input.into(); let procedure_input = input.into();
self.call_after_connect(move |connection, sender| { self.call_after_connect("fail_ai_task_and_return", move |connection, sender| {
connection.procedures().fail_ai_task_and_return_then( connection.procedures().fail_ai_task_and_return_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -174,7 +183,7 @@ impl SpacetimeClient {
) -> Result<AiTaskMutationRecord, SpacetimeClientError> { ) -> Result<AiTaskMutationRecord, SpacetimeClientError> {
let procedure_input = input.into(); let procedure_input = input.into();
self.call_after_connect(move |connection, sender| { self.call_after_connect("cancel_ai_task_and_return", move |connection, sender| {
connection.procedures().cancel_ai_task_and_return_then( connection.procedures().cancel_ai_task_and_return_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {

View File

@@ -7,17 +7,20 @@ impl SpacetimeClient {
) -> Result<Vec<AssetHistoryEntryRecord>, SpacetimeClientError> { ) -> Result<Vec<AssetHistoryEntryRecord>, SpacetimeClientError> {
let procedure_input = input.into(); let procedure_input = input.into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection.procedures().list_asset_history_and_return_then( "list_asset_history_and_return",
procedure_input, move |connection, sender| {
move |_, result| { connection.procedures().list_asset_history_and_return_then(
let mapped = result procedure_input,
.map_err(SpacetimeClientError::from_sdk_error) move |_, result| {
.and_then(map_asset_history_list_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}, .and_then(map_asset_history_list_result);
); send_once(&sender, mapped);
}) },
);
},
)
.await .await
} }
@@ -27,16 +30,19 @@ impl SpacetimeClient {
) -> Result<AssetObjectRecord, SpacetimeClientError> { ) -> Result<AssetObjectRecord, SpacetimeClientError> {
let procedure_input = input.into(); let procedure_input = input.into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "confirm_asset_object_and_return",
.procedures() move |connection, sender| {
.confirm_asset_object_and_return_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .confirm_asset_object_and_return_then(procedure_input, move |_, result| {
.and_then(map_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -46,16 +52,22 @@ impl SpacetimeClient {
) -> Result<AssetEntityBindingRecord, SpacetimeClientError> { ) -> Result<AssetEntityBindingRecord, SpacetimeClientError> {
let procedure_input = input.into(); let procedure_input = input.into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "bind_asset_object_to_entity_and_return",
.procedures() move |connection, sender| {
.bind_asset_object_to_entity_and_return_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .bind_asset_object_to_entity_and_return_then(
.and_then(map_entity_binding_procedure_result); procedure_input,
send_once(&sender, mapped); move |_, result| {
}); let mapped = result
}) .map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_entity_binding_procedure_result);
send_once(&sender, mapped);
},
);
},
)
.await .await
} }
} }

View File

@@ -4,23 +4,26 @@ impl SpacetimeClient {
pub async fn export_auth_store_snapshot_from_tables( pub async fn export_auth_store_snapshot_from_tables(
&self, &self,
) -> Result<AuthStoreSnapshotRecord, SpacetimeClientError> { ) -> Result<AuthStoreSnapshotRecord, SpacetimeClientError> {
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "export_auth_store_snapshot_from_tables",
.procedures() move |connection, sender| {
.export_auth_store_snapshot_from_tables_then(move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .export_auth_store_snapshot_from_tables_then(move |_, result| {
.and_then(map_auth_store_snapshot_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_auth_store_snapshot_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
pub async fn get_auth_store_snapshot( pub async fn get_auth_store_snapshot(
&self, &self,
) -> Result<AuthStoreSnapshotRecord, SpacetimeClientError> { ) -> Result<AuthStoreSnapshotRecord, SpacetimeClientError> {
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_auth_store_snapshot", move |connection, sender| {
connection connection
.procedures() .procedures()
.get_auth_store_snapshot_then(move |_, result| { .get_auth_store_snapshot_then(move |_, result| {
@@ -43,7 +46,7 @@ impl SpacetimeClient {
updated_at_micros, updated_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("upsert_auth_store_snapshot", move |connection, sender| {
connection.procedures().upsert_auth_store_snapshot_then( connection.procedures().upsert_auth_store_snapshot_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -67,23 +70,26 @@ impl SpacetimeClient {
updated_at_micros, updated_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "import_auth_store_snapshot_json",
.procedures() move |connection, sender| {
.import_auth_store_snapshot_json_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .import_auth_store_snapshot_json_then(procedure_input, move |_, result| {
.and_then(map_auth_store_snapshot_import_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_auth_store_snapshot_import_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
pub async fn import_auth_store_snapshot( pub async fn import_auth_store_snapshot(
&self, &self,
) -> Result<AuthStoreSnapshotImportRecord, SpacetimeClientError> { ) -> Result<AuthStoreSnapshotImportRecord, SpacetimeClientError> {
self.call_after_connect(move |connection, sender| { self.call_after_connect("import_auth_store_snapshot", move |connection, sender| {
connection connection
.procedures() .procedures()
.import_auth_store_snapshot_then(move |_, result| { .import_auth_store_snapshot_then(move |_, result| {

View File

@@ -11,7 +11,7 @@ impl SpacetimeClient {
&self, &self,
input: BarkBattleDraftCreateRecordInput, input: BarkBattleDraftCreateRecordInput,
) -> Result<BarkBattleDraftConfigRecord, SpacetimeClientError> { ) -> Result<BarkBattleDraftConfigRecord, SpacetimeClientError> {
self.call_after_connect(move |connection, sender| { self.call_after_connect("create_bark_battle_draft", move |connection, sender| {
connection connection
.procedures() .procedures()
.create_bark_battle_draft_then(input, move |_, result| { .create_bark_battle_draft_then(input, move |_, result| {
@@ -28,16 +28,19 @@ impl SpacetimeClient {
&self, &self,
input: BarkBattleDraftConfigUpsertRecordInput, input: BarkBattleDraftConfigUpsertRecordInput,
) -> Result<BarkBattleDraftConfigRecord, SpacetimeClientError> { ) -> Result<BarkBattleDraftConfigRecord, SpacetimeClientError> {
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "update_bark_battle_draft_config",
.procedures() move |connection, sender| {
.update_bark_battle_draft_config_then(input, move |_, result| { connection
let mapped = result .procedures()
.map_err(|error| SpacetimeClientError::Procedure(error.to_string())) .update_bark_battle_draft_config_then(input, move |_, result| {
.and_then(map_bark_battle_draft_config_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
}); .and_then(map_bark_battle_draft_config_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -45,7 +48,7 @@ impl SpacetimeClient {
&self, &self,
input: BarkBattleWorkPublishRecordInput, input: BarkBattleWorkPublishRecordInput,
) -> Result<BarkBattleRuntimeConfigRecord, SpacetimeClientError> { ) -> Result<BarkBattleRuntimeConfigRecord, SpacetimeClientError> {
self.call_after_connect(move |connection, sender| { self.call_after_connect("publish_bark_battle_work", move |connection, sender| {
connection connection
.procedures() .procedures()
.publish_bark_battle_work_then(input, move |_, result| { .publish_bark_battle_work_then(input, move |_, result| {
@@ -67,16 +70,20 @@ impl SpacetimeClient {
work_id, work_id,
owner_user_id, owner_user_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "get_bark_battle_runtime_config",
.procedures() move |connection, sender| {
.get_bark_battle_runtime_config_then(input, move |_, result| { connection.procedures().get_bark_battle_runtime_config_then(
let mapped = result input,
.map_err(|error| SpacetimeClientError::Procedure(error.to_string())) move |_, result| {
.and_then(map_bark_battle_runtime_config_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
}); .and_then(map_bark_battle_runtime_config_procedure_result);
}) send_once(&sender, mapped);
},
);
},
)
.await .await
} }
@@ -84,7 +91,7 @@ impl SpacetimeClient {
&self, &self,
input: BarkBattleRunStartRecordInput, input: BarkBattleRunStartRecordInput,
) -> Result<BarkBattleRunRecord, SpacetimeClientError> { ) -> Result<BarkBattleRunRecord, SpacetimeClientError> {
self.call_after_connect(move |connection, sender| { self.call_after_connect("start_bark_battle_run", move |connection, sender| {
connection connection
.procedures() .procedures()
.start_bark_battle_run_then(input, move |_, result| { .start_bark_battle_run_then(input, move |_, result| {
@@ -101,7 +108,7 @@ impl SpacetimeClient {
&self, &self,
input: BarkBattleRunFinishRecordInput, input: BarkBattleRunFinishRecordInput,
) -> Result<BarkBattleRunRecord, SpacetimeClientError> { ) -> Result<BarkBattleRunRecord, SpacetimeClientError> {
self.call_after_connect(move |connection, sender| { self.call_after_connect("finish_bark_battle_run", move |connection, sender| {
connection connection
.procedures() .procedures()
.finish_bark_battle_run_then(input, move |_, result| { .finish_bark_battle_run_then(input, move |_, result| {
@@ -123,7 +130,7 @@ impl SpacetimeClient {
run_id, run_id,
owner_user_id, owner_user_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_bark_battle_run", move |connection, sender| {
connection connection
.procedures() .procedures()
.get_bark_battle_run_then(input, move |_, result| { .get_bark_battle_run_then(input, move |_, result| {

View File

@@ -23,7 +23,7 @@ impl SpacetimeClient {
created_at_micros: input.created_at_micros, created_at_micros: input.created_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("create_big_fish_session", move |connection, sender| {
connection.procedures().create_big_fish_session_then( connection.procedures().create_big_fish_session_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -47,7 +47,7 @@ impl SpacetimeClient {
owner_user_id, owner_user_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_big_fish_session", move |connection, sender| {
connection connection
.procedures() .procedures()
.get_big_fish_session_then(procedure_input, move |_, result| { .get_big_fish_session_then(procedure_input, move |_, result| {
@@ -87,7 +87,7 @@ impl SpacetimeClient {
&self, &self,
procedure_input: BigFishWorksListInput, procedure_input: BigFishWorksListInput,
) -> Result<Vec<BigFishWorkSummaryRecord>, SpacetimeClientError> { ) -> Result<Vec<BigFishWorkSummaryRecord>, SpacetimeClientError> {
self.call_after_connect(move |connection, sender| { self.call_after_connect("list_big_fish_works", move |connection, sender| {
let fallback_owner_user_id = if procedure_input.published_only { let fallback_owner_user_id = if procedure_input.published_only {
None None
} else { } else {
@@ -120,7 +120,7 @@ impl SpacetimeClient {
owner_user_id, owner_user_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("delete_big_fish_work", move |connection, sender| {
let fallback_owner_user_id = Some(procedure_input.owner_user_id.clone()); let fallback_owner_user_id = Some(procedure_input.owner_user_id.clone());
connection connection
.procedures() .procedures()
@@ -152,7 +152,7 @@ impl SpacetimeClient {
submitted_at_micros: input.submitted_at_micros, submitted_at_micros: input.submitted_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("submit_big_fish_message", move |connection, sender| {
connection.procedures().submit_big_fish_message_then( connection.procedures().submit_big_fish_message_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -182,16 +182,22 @@ impl SpacetimeClient {
updated_at_micros: input.updated_at_micros, updated_at_micros: input.updated_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "finalize_big_fish_agent_message_turn",
.procedures() move |connection, sender| {
.finalize_big_fish_agent_message_turn_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .finalize_big_fish_agent_message_turn_then(
.and_then(map_big_fish_session_procedure_result); procedure_input,
send_once(&sender, mapped); move |_, result| {
}); let mapped = result
}) .map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_big_fish_session_procedure_result);
send_once(&sender, mapped);
},
);
},
)
.await .await
} }
@@ -206,7 +212,7 @@ impl SpacetimeClient {
compiled_at_micros: input.compiled_at_micros, compiled_at_micros: input.compiled_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("compile_big_fish_draft", move |connection, sender| {
connection.procedures().compile_big_fish_draft_then( connection.procedures().compile_big_fish_draft_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -234,7 +240,7 @@ impl SpacetimeClient {
generated_at_micros: input.generated_at_micros, generated_at_micros: input.generated_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("generate_big_fish_asset", move |connection, sender| {
connection.procedures().generate_big_fish_asset_then( connection.procedures().generate_big_fish_asset_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -260,7 +266,7 @@ impl SpacetimeClient {
published_at_micros, published_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("publish_big_fish_game", move |connection, sender| {
connection.procedures().publish_big_fish_game_then( connection.procedures().publish_big_fish_game_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -285,7 +291,7 @@ impl SpacetimeClient {
played_at_micros: input.reported_at_micros, played_at_micros: input.reported_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("record_big_fish_play", move |connection, sender| {
connection connection
.procedures() .procedures()
.record_big_fish_play_then(procedure_input, move |_, result| { .record_big_fish_play_then(procedure_input, move |_, result| {
@@ -309,7 +315,7 @@ impl SpacetimeClient {
started_at_micros: input.started_at_micros, started_at_micros: input.started_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("start_big_fish_run", move |connection, sender| {
connection connection
.procedures() .procedures()
.start_big_fish_run_then(procedure_input, move |_, result| { .start_big_fish_run_then(procedure_input, move |_, result| {
@@ -332,7 +338,7 @@ impl SpacetimeClient {
liked_at_micros: input.liked_at_micros, liked_at_micros: input.liked_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("record_big_fish_like", move |connection, sender| {
connection connection
.procedures() .procedures()
.record_big_fish_like_then(procedure_input, move |_, result| { .record_big_fish_like_then(procedure_input, move |_, result| {
@@ -355,7 +361,7 @@ impl SpacetimeClient {
owner_user_id, owner_user_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_big_fish_run", move |connection, sender| {
connection connection
.procedures() .procedures()
.get_big_fish_run_then(procedure_input, move |_, result| { .get_big_fish_run_then(procedure_input, move |_, result| {
@@ -380,7 +386,7 @@ impl SpacetimeClient {
remixed_at_micros: input.remixed_at_micros, remixed_at_micros: input.remixed_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("remix_big_fish_work", move |connection, sender| {
connection connection
.procedures() .procedures()
.remix_big_fish_work_then(procedure_input, move |_, result| { .remix_big_fish_work_then(procedure_input, move |_, result| {
@@ -405,7 +411,7 @@ impl SpacetimeClient {
submitted_at_micros: input.submitted_at_micros, submitted_at_micros: input.submitted_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("submit_big_fish_input", move |connection, sender| {
connection.procedures().submit_big_fish_input_then( connection.procedures().submit_big_fish_input_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {

View File

@@ -9,17 +9,20 @@ impl SpacetimeClient {
validate_battle_state_input(&input).map_err(SpacetimeClientError::validation_failed)?; validate_battle_state_input(&input).map_err(SpacetimeClientError::validation_failed)?;
let procedure_input = input.into(); let procedure_input = input.into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection.procedures().create_battle_state_and_return_then( "create_battle_state_and_return",
procedure_input, move |connection, sender| {
move |_, result| { connection.procedures().create_battle_state_and_return_then(
let mapped = result procedure_input,
.map_err(SpacetimeClientError::from_sdk_error) move |_, result| {
.and_then(map_battle_state_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}, .and_then(map_battle_state_procedure_result);
); send_once(&sender, mapped);
}) },
);
},
)
.await .await
} }
@@ -31,7 +34,7 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_battle_state", move |connection, sender| {
connection connection
.procedures() .procedures()
.get_battle_state_then(procedure_input, move |_, result| { .get_battle_state_then(procedure_input, move |_, result| {
@@ -52,16 +55,19 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)?; .map_err(SpacetimeClientError::validation_failed)?;
let procedure_input = input.into(); let procedure_input = input.into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "resolve_combat_action_and_return",
.procedures() move |connection, sender| {
.resolve_combat_action_and_return_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .resolve_combat_action_and_return_then(procedure_input, move |_, result| {
.and_then(map_resolve_combat_action_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_resolve_combat_action_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
} }

View File

@@ -12,7 +12,7 @@ impl SpacetimeClient {
) -> Result<Vec<CustomWorldLibraryEntryRecord>, SpacetimeClientError> { ) -> Result<Vec<CustomWorldLibraryEntryRecord>, SpacetimeClientError> {
let procedure_input = CustomWorldProfileListInput { owner_user_id }; let procedure_input = CustomWorldProfileListInput { owner_user_id };
self.call_after_connect(move |connection, sender| { self.call_after_connect("list_custom_world_profiles", move |connection, sender| {
connection.procedures().list_custom_world_profiles_then( connection.procedures().list_custom_world_profiles_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -36,16 +36,19 @@ impl SpacetimeClient {
profile_id, profile_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "get_custom_world_library_detail",
.procedures() move |connection, sender| {
.get_custom_world_library_detail_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .get_custom_world_library_detail_then(procedure_input, move |_, result| {
.and_then(map_custom_world_library_detail_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_custom_world_library_detail_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -55,16 +58,22 @@ impl SpacetimeClient {
) -> Result<CustomWorldLibraryMutationRecord, SpacetimeClientError> { ) -> Result<CustomWorldLibraryMutationRecord, SpacetimeClientError> {
let procedure_input = input.into(); let procedure_input = input.into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "upsert_custom_world_profile_and_return",
.procedures() move |connection, sender| {
.upsert_custom_world_profile_and_return_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .upsert_custom_world_profile_and_return_then(
.and_then(map_custom_world_library_mutation_result); procedure_input,
send_once(&sender, mapped); move |_, result| {
}); let mapped = result
}) .map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_custom_world_library_mutation_result);
send_once(&sender, mapped);
},
);
},
)
.await .await
} }
@@ -86,16 +95,22 @@ impl SpacetimeClient {
published_at_micros, published_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "publish_custom_world_profile_and_return",
.procedures() move |connection, sender| {
.publish_custom_world_profile_and_return_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .publish_custom_world_profile_and_return_then(
.and_then(map_custom_world_library_mutation_result); procedure_input,
send_once(&sender, mapped); move |_, result| {
}); let mapped = result
}) .map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_custom_world_library_mutation_result);
send_once(&sender, mapped);
},
);
},
)
.await .await
} }
@@ -113,19 +128,22 @@ impl SpacetimeClient {
updated_at_micros, updated_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "unpublish_custom_world_profile_and_return",
.procedures() move |connection, sender| {
.unpublish_custom_world_profile_and_return_then( connection
procedure_input, .procedures()
move |_, result| { .unpublish_custom_world_profile_and_return_then(
let mapped = result procedure_input,
.map_err(SpacetimeClientError::from_sdk_error) move |_, result| {
.and_then(map_custom_world_library_mutation_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}, .and_then(map_custom_world_library_mutation_result);
); send_once(&sender, mapped);
}) },
);
},
)
.await .await
} }
@@ -141,32 +159,41 @@ impl SpacetimeClient {
deleted_at_micros, deleted_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "delete_custom_world_profile_and_return",
.procedures() move |connection, sender| {
.delete_custom_world_profile_and_return_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .delete_custom_world_profile_and_return_then(
.and_then(map_custom_world_profile_list_result); procedure_input,
send_once(&sender, mapped); move |_, result| {
}); let mapped = result
}) .map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_custom_world_profile_list_result);
send_once(&sender, mapped);
},
);
},
)
.await .await
} }
pub async fn list_custom_world_gallery_entries( pub async fn list_custom_world_gallery_entries(
&self, &self,
) -> Result<Vec<CustomWorldGalleryEntryRecord>, SpacetimeClientError> { ) -> Result<Vec<CustomWorldGalleryEntryRecord>, SpacetimeClientError> {
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "list_custom_world_gallery_entries",
.procedures() move |connection, sender| {
.list_custom_world_gallery_entries_then(move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .list_custom_world_gallery_entries_then(move |_, result| {
.and_then(map_custom_world_gallery_list_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_custom_world_gallery_list_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -180,16 +207,19 @@ impl SpacetimeClient {
profile_id, profile_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "get_custom_world_gallery_detail",
.procedures() move |connection, sender| {
.get_custom_world_gallery_detail_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .get_custom_world_gallery_detail_then(procedure_input, move |_, result| {
.and_then(map_custom_world_library_mutation_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_custom_world_library_mutation_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -199,16 +229,22 @@ impl SpacetimeClient {
) -> Result<CustomWorldLibraryMutationRecord, SpacetimeClientError> { ) -> Result<CustomWorldLibraryMutationRecord, SpacetimeClientError> {
let procedure_input = CustomWorldGalleryDetailByCodeInput { public_work_code }; let procedure_input = CustomWorldGalleryDetailByCodeInput { public_work_code };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "get_custom_world_gallery_detail_by_code",
.procedures() move |connection, sender| {
.get_custom_world_gallery_detail_by_code_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .get_custom_world_gallery_detail_by_code_then(
.and_then(map_custom_world_library_mutation_result); procedure_input,
send_once(&sender, mapped); move |_, result| {
}); let mapped = result
}) .map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_custom_world_library_mutation_result);
send_once(&sender, mapped);
},
);
},
)
.await .await
} }
@@ -225,7 +261,7 @@ impl SpacetimeClient {
remixed_at_micros: input.remixed_at_micros, remixed_at_micros: input.remixed_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("remix_custom_world_profile", move |connection, sender| {
connection.procedures().remix_custom_world_profile_then( connection.procedures().remix_custom_world_profile_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -249,16 +285,19 @@ impl SpacetimeClient {
played_at_micros: input.played_at_micros, played_at_micros: input.played_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "record_custom_world_profile_play",
.procedures() move |connection, sender| {
.record_custom_world_profile_play_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(|error| SpacetimeClientError::Procedure(error.to_string())) .record_custom_world_profile_play_then(procedure_input, move |_, result| {
.and_then(map_custom_world_library_mutation_result); let mapped = result
send_once(&sender, mapped); .map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
}); .and_then(map_custom_world_library_mutation_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -273,16 +312,19 @@ impl SpacetimeClient {
liked_at_micros: input.liked_at_micros, liked_at_micros: input.liked_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "record_custom_world_profile_like",
.procedures() move |connection, sender| {
.record_custom_world_profile_like_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(|error| SpacetimeClientError::Procedure(error.to_string())) .record_custom_world_profile_like_then(procedure_input, move |_, result| {
.and_then(map_custom_world_library_mutation_result); let mapped = result
send_once(&sender, mapped); .map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
}); .and_then(map_custom_world_library_mutation_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -292,7 +334,7 @@ impl SpacetimeClient {
) -> Result<CustomWorldPublishWorldRecord, SpacetimeClientError> { ) -> Result<CustomWorldPublishWorldRecord, SpacetimeClientError> {
let procedure_input = input.into(); let procedure_input = input.into();
self.call_after_connect(move |connection, sender| { self.call_after_connect("publish_custom_world_world", move |connection, sender| {
connection.procedures().publish_custom_world_world_then( connection.procedures().publish_custom_world_world_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -331,16 +373,19 @@ impl SpacetimeClient {
created_at_micros: input.created_at_micros, created_at_micros: input.created_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "create_custom_world_agent_session",
.procedures() move |connection, sender| {
.create_custom_world_agent_session_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .create_custom_world_agent_session_then(procedure_input, move |_, result| {
.and_then(map_custom_world_agent_session_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_custom_world_agent_session_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -354,17 +399,20 @@ impl SpacetimeClient {
owner_user_id, owner_user_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection.procedures().get_custom_world_agent_session_then( "get_custom_world_agent_session",
procedure_input, move |connection, sender| {
move |_, result| { connection.procedures().get_custom_world_agent_session_then(
let mapped = result procedure_input,
.map_err(SpacetimeClientError::from_sdk_error) move |_, result| {
.and_then(map_custom_world_agent_session_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}, .and_then(map_custom_world_agent_session_procedure_result);
); send_once(&sender, mapped);
}) },
);
},
)
.await .await
} }
@@ -374,7 +422,7 @@ impl SpacetimeClient {
) -> Result<Vec<CustomWorldWorkSummaryRecord>, SpacetimeClientError> { ) -> Result<Vec<CustomWorldWorkSummaryRecord>, SpacetimeClientError> {
let procedure_input = CustomWorldWorksListInput { owner_user_id }; let procedure_input = CustomWorldWorksListInput { owner_user_id };
self.call_after_connect(move |connection, sender| { self.call_after_connect("list_custom_world_works", move |connection, sender| {
connection.procedures().list_custom_world_works_then( connection.procedures().list_custom_world_works_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -398,16 +446,19 @@ impl SpacetimeClient {
owner_user_id, owner_user_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "delete_custom_world_agent_session",
.procedures() move |connection, sender| {
.delete_custom_world_agent_session_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .delete_custom_world_agent_session_then(procedure_input, move |_, result| {
.and_then(map_custom_world_works_list_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_custom_world_works_list_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -423,16 +474,19 @@ impl SpacetimeClient {
card_id, card_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "get_custom_world_agent_card_detail",
.procedures() move |connection, sender| {
.get_custom_world_agent_card_detail_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .get_custom_world_agent_card_detail_then(procedure_input, move |_, result| {
.and_then(map_custom_world_draft_card_detail_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_custom_world_draft_card_detail_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -449,16 +503,19 @@ impl SpacetimeClient {
submitted_at_micros: input.submitted_at_micros, submitted_at_micros: input.submitted_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "execute_custom_world_agent_action",
.procedures() move |connection, sender| {
.execute_custom_world_agent_action_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .execute_custom_world_agent_action_then(procedure_input, move |_, result| {
.and_then(map_custom_world_agent_action_execute_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_custom_world_agent_action_execute_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -475,16 +532,19 @@ impl SpacetimeClient {
submitted_at_micros: input.submitted_at_micros, submitted_at_micros: input.submitted_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "submit_custom_world_agent_message",
.procedures() move |connection, sender| {
.submit_custom_world_agent_message_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .submit_custom_world_agent_message_then(procedure_input, move |_, result| {
.and_then(map_custom_world_agent_operation_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_custom_world_agent_operation_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -521,19 +581,22 @@ impl SpacetimeClient {
updated_at_micros: input.updated_at_micros, updated_at_micros: input.updated_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "finalize_custom_world_agent_message_turn",
.procedures() move |connection, sender| {
.finalize_custom_world_agent_message_turn_then( connection
procedure_input, .procedures()
move |_, result| { .finalize_custom_world_agent_message_turn_then(
let mapped = result procedure_input,
.map_err(SpacetimeClientError::from_sdk_error) move |_, result| {
.and_then(map_custom_world_agent_operation_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}, .and_then(map_custom_world_agent_operation_procedure_result);
); send_once(&sender, mapped);
}) },
);
},
)
.await .await
} }
@@ -556,19 +619,22 @@ impl SpacetimeClient {
updated_at_micros: input.updated_at_micros, updated_at_micros: input.updated_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "upsert_custom_world_agent_operation_progress",
.procedures() move |connection, sender| {
.upsert_custom_world_agent_operation_progress_then( connection
procedure_input, .procedures()
move |_, result| { .upsert_custom_world_agent_operation_progress_then(
let mapped = result procedure_input,
.map_err(SpacetimeClientError::from_sdk_error) move |_, result| {
.and_then(map_custom_world_agent_operation_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}, .and_then(map_custom_world_agent_operation_procedure_result);
); send_once(&sender, mapped);
}) },
);
},
)
.await .await
} }
@@ -584,16 +650,19 @@ impl SpacetimeClient {
operation_id, operation_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "get_custom_world_agent_operation",
.procedures() move |connection, sender| {
.get_custom_world_agent_operation_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .get_custom_world_agent_operation_then(procedure_input, move |_, result| {
.and_then(map_custom_world_agent_operation_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_custom_world_agent_operation_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
} }

View File

@@ -11,7 +11,7 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_runtime_inventory_state", move |connection, sender| {
connection.procedures().get_runtime_inventory_state_then( connection.procedures().get_runtime_inventory_state_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {

View File

@@ -3,6 +3,7 @@
pub mod module_bindings; pub mod module_bindings;
mod mapper; mod mapper;
mod telemetry;
use mapper::*; use mapper::*;
pub use mapper::{ pub use mapper::{
AiResultReferenceRecord, AiTaskMutationRecord, AiTaskRecord, AiTaskStageRecord, AiResultReferenceRecord, AiTaskMutationRecord, AiTaskRecord, AiTaskStageRecord,
@@ -142,6 +143,24 @@ use module_npc::{
NpcStanceProfile as DomainNpcStanceProfile, NpcStateSnapshot as DomainNpcStateSnapshot, NpcStanceProfile as DomainNpcStanceProfile, NpcStateSnapshot as DomainNpcStateSnapshot,
ResolveNpcInteractionInput as DomainResolveNpcInteractionInput, ResolveNpcInteractionInput as DomainResolveNpcInteractionInput,
}; };
use module_puzzle::{
PuzzleAgentMessageSnapshot as DomainPuzzleAgentMessageSnapshot,
PuzzleAgentSessionSnapshot as DomainPuzzleAgentSessionSnapshot,
PuzzleAgentSuggestedAction as DomainPuzzleAgentSuggestedAction,
PuzzleAnchorItem as DomainPuzzleAnchorItem, PuzzleAnchorPack as DomainPuzzleAnchorPack,
PuzzleBoardSnapshot as DomainPuzzleBoardSnapshot,
PuzzleCellPosition as DomainPuzzleCellPosition,
PuzzleCreatorIntent as DomainPuzzleCreatorIntent, PuzzleDraftLevel as DomainPuzzleDraftLevel,
PuzzleGeneratedImageCandidate as DomainPuzzleGeneratedImageCandidate,
PuzzleMergedGroupState as DomainPuzzleMergedGroupState,
PuzzlePieceState as DomainPuzzlePieceState, PuzzleResultDraft as DomainPuzzleResultDraft,
PuzzleResultPreviewBlocker as DomainPuzzleResultPreviewBlocker,
PuzzleResultPreviewEnvelope as DomainPuzzleResultPreviewEnvelope,
PuzzleResultPreviewFinding as DomainPuzzleResultPreviewFinding,
PuzzleRunSnapshot as DomainPuzzleRunSnapshot,
PuzzleRuntimeLevelSnapshot as DomainPuzzleRuntimeLevelSnapshot,
PuzzleWorkProfile as DomainPuzzleWorkProfile,
};
use module_runtime::{ use module_runtime::{
AnalyticsMetricQueryResponse as DomainAnalyticsMetricQueryResponse, RuntimeBrowseHistoryRecord, AnalyticsMetricQueryResponse as DomainAnalyticsMetricQueryResponse, RuntimeBrowseHistoryRecord,
RuntimePlatformTheme as DomainRuntimePlatformTheme, RuntimeProfileDashboardRecord, RuntimePlatformTheme as DomainRuntimePlatformTheme, RuntimeProfileDashboardRecord,
@@ -307,56 +326,72 @@ impl SpacetimeClient {
async fn call_after_connect<T>( async fn call_after_connect<T>(
&self, &self,
procedure: &'static str,
call: impl FnOnce(&DbConnection, ProcedureResultSender<T>) + Send + 'static, call: impl FnOnce(&DbConnection, ProcedureResultSender<T>) + Send + 'static,
) -> Result<T, SpacetimeClientError> ) -> Result<T, SpacetimeClientError>
where where
T: Send + 'static, T: Send + 'static,
{ {
let metrics_guard = telemetry::begin_procedure(procedure);
let (sender, receiver) = oneshot::channel(); let (sender, receiver) = oneshot::channel();
let result_sender = Arc::new(Mutex::new(Some(sender))); let result_sender = Arc::new(Mutex::new(Some(sender)));
let lease = self.acquire_connection().await?; let final_result = match self.acquire_connection().await {
let final_result = if let Some(connection) = lease.connection.as_ref() { Ok(lease) => {
call(&connection.connection, result_sender.clone()); let result = if let Some(connection) = lease.connection.as_ref() {
match timeout(self.config.procedure_timeout, receiver).await { call(&connection.connection, result_sender.clone());
Ok(inner) => match inner { match timeout(self.config.procedure_timeout, receiver).await {
Ok(value) => value, Ok(inner) => match inner {
Err(_) => Err(SpacetimeClientError::ConnectDropped), Ok(value) => value,
}, Err(_) => Err(SpacetimeClientError::ConnectDropped),
Err(_) => Err(Self::resolve_timeout_error(Some(connection))), },
Err(_) => Err(Self::resolve_timeout_error(Some(connection))),
}
} else {
Err(SpacetimeClientError::Runtime(
"SpacetimeDB 连接租约缺少连接".to_string(),
))
};
self.release_connection(lease).await;
result
} }
} else { Err(error) => Err(error),
Err(SpacetimeClientError::Runtime(
"SpacetimeDB 连接租约缺少连接".to_string(),
))
}; };
self.release_connection(lease).await;
metrics_guard.finish(&final_result);
final_result final_result
} }
async fn call_reducer_after_connect( async fn call_reducer_after_connect(
&self, &self,
procedure: &'static str,
call: impl FnOnce(&DbConnection, ReducerResultSender) + Send + 'static, call: impl FnOnce(&DbConnection, ReducerResultSender) + Send + 'static,
) -> Result<(), SpacetimeClientError> { ) -> Result<(), SpacetimeClientError> {
let metrics_guard = telemetry::begin_procedure(procedure);
let (sender, receiver) = oneshot::channel(); let (sender, receiver) = oneshot::channel();
let result_sender = Arc::new(Mutex::new(Some(sender))); let result_sender = Arc::new(Mutex::new(Some(sender)));
let lease = self.acquire_connection().await?; let final_result = match self.acquire_connection().await {
let final_result = if let Some(connection) = lease.connection.as_ref() { Ok(lease) => {
call(&connection.connection, result_sender.clone()); let result = if let Some(connection) = lease.connection.as_ref() {
match timeout(self.config.procedure_timeout, receiver).await { call(&connection.connection, result_sender.clone());
Ok(inner) => match inner { match timeout(self.config.procedure_timeout, receiver).await {
Ok(value) => value, Ok(inner) => match inner {
Err(_) => Err(SpacetimeClientError::ConnectDropped), Ok(value) => value,
}, Err(_) => Err(SpacetimeClientError::ConnectDropped),
Err(_) => Err(Self::resolve_timeout_error(Some(connection))), },
Err(_) => Err(Self::resolve_timeout_error(Some(connection))),
}
} else {
Err(SpacetimeClientError::Runtime(
"SpacetimeDB 连接租约缺少连接".to_string(),
))
};
self.release_connection(lease).await;
result
} }
} else { Err(error) => Err(error),
Err(SpacetimeClientError::Runtime(
"SpacetimeDB 连接租约缺少连接".to_string(),
))
}; };
self.release_connection(lease).await;
metrics_guard.finish(&final_result);
final_result final_result
} }
@@ -488,7 +523,6 @@ impl SpacetimeClient {
let mut subscriptions = Vec::new(); let mut subscriptions = Vec::new();
for query in [ for query in [
"SELECT * FROM puzzle_gallery_view", "SELECT * FROM puzzle_gallery_view",
"SELECT * FROM public_work_play_daily_stat WHERE source_type = 'puzzle'",
] { ] {
let (sender, receiver) = oneshot::channel::<Result<(), SpacetimeClientError>>(); let (sender, receiver) = oneshot::channel::<Result<(), SpacetimeClientError>>();
let applied_sender = Arc::new(Mutex::new(Some(sender))); let applied_sender = Arc::new(Mutex::new(Some(sender)));

View File

@@ -16,17 +16,20 @@ impl SpacetimeClient {
created_at_micros: input.created_at_micros, created_at_micros: input.created_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection.procedures().create_match_3_d_agent_session_then( "create_match_3_d_agent_session",
procedure_input, move |connection, sender| {
move |_, result| { connection.procedures().create_match_3_d_agent_session_then(
let mapped = result procedure_input,
.map_err(|error| SpacetimeClientError::Procedure(error.to_string())) move |_, result| {
.and_then(map_match3d_agent_session_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
}, .and_then(map_match3d_agent_session_procedure_result);
); send_once(&sender, mapped);
}) },
);
},
)
.await .await
} }
@@ -40,7 +43,7 @@ impl SpacetimeClient {
owner_user_id, owner_user_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_match_3_d_agent_session", move |connection, sender| {
connection.procedures().get_match_3_d_agent_session_then( connection.procedures().get_match_3_d_agent_session_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -66,17 +69,20 @@ impl SpacetimeClient {
submitted_at_micros: input.submitted_at_micros, submitted_at_micros: input.submitted_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection.procedures().submit_match_3_d_agent_message_then( "submit_match_3_d_agent_message",
procedure_input, move |connection, sender| {
move |_, result| { connection.procedures().submit_match_3_d_agent_message_then(
let mapped = result procedure_input,
.map_err(|error| SpacetimeClientError::Procedure(error.to_string())) move |_, result| {
.and_then(map_match3d_agent_session_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
}, .and_then(map_match3d_agent_session_procedure_result);
); send_once(&sender, mapped);
}) },
);
},
)
.await .await
} }
@@ -96,16 +102,22 @@ impl SpacetimeClient {
error_message: input.error_message, error_message: input.error_message,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "finalize_match_3_d_agent_message_turn",
.procedures() move |connection, sender| {
.finalize_match_3_d_agent_message_turn_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(|error| SpacetimeClientError::Procedure(error.to_string())) .finalize_match_3_d_agent_message_turn_then(
.and_then(map_match3d_agent_session_procedure_result); procedure_input,
send_once(&sender, mapped); move |_, result| {
}); let mapped = result
}) .map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
.and_then(map_match3d_agent_session_procedure_result);
send_once(&sender, mapped);
},
);
},
)
.await .await
} }
@@ -127,7 +139,7 @@ impl SpacetimeClient {
generated_item_assets_json: input.generated_item_assets_json, generated_item_assets_json: input.generated_item_assets_json,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("compile_match_3_d_draft", move |connection, sender| {
connection.procedures().compile_match_3_d_draft_then( connection.procedures().compile_match_3_d_draft_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -159,7 +171,7 @@ impl SpacetimeClient {
updated_at_micros: input.updated_at_micros, updated_at_micros: input.updated_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("update_match_3_d_work", move |connection, sender| {
connection.procedures().update_match_3_d_work_then( connection.procedures().update_match_3_d_work_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -185,7 +197,7 @@ impl SpacetimeClient {
published_at_micros, published_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("publish_match_3_d_work", move |connection, sender| {
connection.procedures().publish_match_3_d_work_then( connection.procedures().publish_match_3_d_work_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -225,7 +237,7 @@ impl SpacetimeClient {
&self, &self,
procedure_input: Match3DWorksListInput, procedure_input: Match3DWorksListInput,
) -> Result<Vec<Match3DWorkProfileRecord>, SpacetimeClientError> { ) -> Result<Vec<Match3DWorkProfileRecord>, SpacetimeClientError> {
self.call_after_connect(move |connection, sender| { self.call_after_connect("list_match_3_d_works", move |connection, sender| {
connection connection
.procedures() .procedures()
.list_match_3_d_works_then(procedure_input, move |_, result| { .list_match_3_d_works_then(procedure_input, move |_, result| {
@@ -248,7 +260,7 @@ impl SpacetimeClient {
owner_user_id, owner_user_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_match_3_d_work_detail", move |connection, sender| {
connection.procedures().get_match_3_d_work_detail_then( connection.procedures().get_match_3_d_work_detail_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -272,7 +284,7 @@ impl SpacetimeClient {
owner_user_id, owner_user_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("delete_match_3_d_work", move |connection, sender| {
connection.procedures().delete_match_3_d_work_then( connection.procedures().delete_match_3_d_work_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -299,7 +311,7 @@ impl SpacetimeClient {
item_type_count_override: input.item_type_count_override, item_type_count_override: input.item_type_count_override,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("start_match_3_d_run", move |connection, sender| {
connection connection
.procedures() .procedures()
.start_match_3_d_run_then(procedure_input, move |_, result| { .start_match_3_d_run_then(procedure_input, move |_, result| {
@@ -327,7 +339,7 @@ impl SpacetimeClient {
owner_user_id, owner_user_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_match_3_d_run", move |connection, sender| {
connection connection
.procedures() .procedures()
.get_match_3_d_run_then(procedure_input, move |_, result| { .get_match_3_d_run_then(procedure_input, move |_, result| {
@@ -359,7 +371,7 @@ impl SpacetimeClient {
clicked_at_ms: input.clicked_at_ms, clicked_at_ms: input.clicked_at_ms,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("click_match_3_d_item", move |connection, sender| {
connection connection
.procedures() .procedures()
.click_match_3_d_item_then(procedure_input, move |_, result| { .click_match_3_d_item_then(procedure_input, move |_, result| {
@@ -390,7 +402,7 @@ impl SpacetimeClient {
stopped_at_ms: input.stopped_at_ms, stopped_at_ms: input.stopped_at_ms,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("stop_match_3_d_run", move |connection, sender| {
connection connection
.procedures() .procedures()
.stop_match_3_d_run_then(procedure_input, move |_, result| { .stop_match_3_d_run_then(procedure_input, move |_, result| {
@@ -419,7 +431,7 @@ impl SpacetimeClient {
restarted_at_ms: input.restarted_at_ms, restarted_at_ms: input.restarted_at_ms,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("restart_match_3_d_run", move |connection, sender| {
connection.procedures().restart_match_3_d_run_then( connection.procedures().restart_match_3_d_run_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -448,7 +460,7 @@ impl SpacetimeClient {
finished_at_ms: input.finished_at_ms, finished_at_ms: input.finished_at_ms,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("finish_match_3_d_time_up", move |connection, sender| {
connection.procedures().finish_match_3_d_time_up_then( connection.procedures().finish_match_3_d_time_up_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {

View File

@@ -95,7 +95,6 @@ pub mod auth_store_snapshot_type;
pub mod auth_store_snapshot_upsert_input_type; pub mod auth_store_snapshot_upsert_input_type;
pub mod authorize_database_migration_operator_procedure; pub mod authorize_database_migration_operator_procedure;
pub mod bark_battle_draft_config_row_type; pub mod bark_battle_draft_config_row_type;
pub mod bark_battle_draft_config_snapshot_type;
pub mod bark_battle_draft_config_table; pub mod bark_battle_draft_config_table;
pub mod bark_battle_draft_config_upsert_input_type; pub mod bark_battle_draft_config_upsert_input_type;
pub mod bark_battle_draft_create_input_type; pub mod bark_battle_draft_create_input_type;
@@ -108,10 +107,8 @@ pub mod bark_battle_published_config_row_type;
pub mod bark_battle_published_config_table; pub mod bark_battle_published_config_table;
pub mod bark_battle_run_finish_input_type; pub mod bark_battle_run_finish_input_type;
pub mod bark_battle_run_get_input_type; pub mod bark_battle_run_get_input_type;
pub mod bark_battle_run_snapshot_type;
pub mod bark_battle_run_start_input_type; pub mod bark_battle_run_start_input_type;
pub mod bark_battle_runtime_config_get_input_type; pub mod bark_battle_runtime_config_get_input_type;
pub mod bark_battle_runtime_config_snapshot_type;
pub mod bark_battle_runtime_run_row_type; pub mod bark_battle_runtime_run_row_type;
pub mod bark_battle_runtime_run_table; pub mod bark_battle_runtime_run_table;
pub mod bark_battle_score_record_row_type; pub mod bark_battle_score_record_row_type;
@@ -163,20 +160,16 @@ pub mod big_fish_run_get_input_type;
pub mod big_fish_run_procedure_result_type; pub mod big_fish_run_procedure_result_type;
pub mod big_fish_run_start_input_type; pub mod big_fish_run_start_input_type;
pub mod big_fish_run_status_type; pub mod big_fish_run_status_type;
pub mod big_fish_runtime_entity_snapshot_type;
pub mod big_fish_runtime_params_type; pub mod big_fish_runtime_params_type;
pub mod big_fish_runtime_run_table; pub mod big_fish_runtime_run_table;
pub mod big_fish_runtime_run_type; pub mod big_fish_runtime_run_type;
pub mod big_fish_runtime_snapshot_type;
pub mod big_fish_session_create_input_type; pub mod big_fish_session_create_input_type;
pub mod big_fish_session_get_input_type; pub mod big_fish_session_get_input_type;
pub mod big_fish_session_procedure_result_type; pub mod big_fish_session_procedure_result_type;
pub mod big_fish_session_snapshot_type; pub mod big_fish_session_snapshot_type;
pub mod big_fish_vector_2_type;
pub mod big_fish_work_delete_input_type; pub mod big_fish_work_delete_input_type;
pub mod big_fish_work_like_record_input_type; pub mod big_fish_work_like_record_input_type;
pub mod big_fish_work_remix_input_type; pub mod big_fish_work_remix_input_type;
pub mod big_fish_work_summary_snapshot_type;
pub mod big_fish_works_list_input_type; pub mod big_fish_works_list_input_type;
pub mod big_fish_works_procedure_result_type; pub mod big_fish_works_procedure_result_type;
pub mod bind_asset_object_to_entity_and_return_procedure; pub mod bind_asset_object_to_entity_and_return_procedure;
@@ -409,38 +402,30 @@ pub mod list_visual_novel_works_procedure;
pub mod mark_profile_recharge_order_paid_and_return_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_finalize_input_type;
pub mod match_3_d_agent_message_row_type; pub mod match_3_d_agent_message_row_type;
pub mod match_3_d_agent_message_snapshot_type;
pub mod match_3_d_agent_message_submit_input_type; pub mod match_3_d_agent_message_submit_input_type;
pub mod match_3_d_agent_message_table; pub mod match_3_d_agent_message_table;
pub mod match_3_d_agent_session_create_input_type; pub mod match_3_d_agent_session_create_input_type;
pub mod match_3_d_agent_session_get_input_type; pub mod match_3_d_agent_session_get_input_type;
pub mod match_3_d_agent_session_procedure_result_type; pub mod match_3_d_agent_session_procedure_result_type;
pub mod match_3_d_agent_session_row_type; pub mod match_3_d_agent_session_row_type;
pub mod match_3_d_agent_session_snapshot_type;
pub mod match_3_d_agent_session_table; pub mod match_3_d_agent_session_table;
pub mod match_3_d_click_item_procedure_result_type; pub mod match_3_d_click_item_procedure_result_type;
pub mod match_3_d_creator_config_snapshot_type;
pub mod match_3_d_draft_compile_input_type; pub mod match_3_d_draft_compile_input_type;
pub mod match_3_d_draft_snapshot_type;
pub mod match_3_d_item_snapshot_type;
pub mod match_3_d_run_click_input_type; pub mod match_3_d_run_click_input_type;
pub mod match_3_d_run_get_input_type; pub mod match_3_d_run_get_input_type;
pub mod match_3_d_run_procedure_result_type; pub mod match_3_d_run_procedure_result_type;
pub mod match_3_d_run_restart_input_type; pub mod match_3_d_run_restart_input_type;
pub mod match_3_d_run_snapshot_type;
pub mod match_3_d_run_start_input_type; pub mod match_3_d_run_start_input_type;
pub mod match_3_d_run_stop_input_type; pub mod match_3_d_run_stop_input_type;
pub mod match_3_d_run_time_up_input_type; pub mod match_3_d_run_time_up_input_type;
pub mod match_3_d_runtime_run_row_type; pub mod match_3_d_runtime_run_row_type;
pub mod match_3_d_runtime_run_table; pub mod match_3_d_runtime_run_table;
pub mod match_3_d_tray_slot_snapshot_type;
pub mod match_3_d_work_delete_input_type; pub mod match_3_d_work_delete_input_type;
pub mod match_3_d_work_get_input_type; pub mod match_3_d_work_get_input_type;
pub mod match_3_d_work_procedure_result_type; pub mod match_3_d_work_procedure_result_type;
pub mod match_3_d_work_profile_row_type; pub mod match_3_d_work_profile_row_type;
pub mod match_3_d_work_profile_table; pub mod match_3_d_work_profile_table;
pub mod match_3_d_work_publish_input_type; pub mod match_3_d_work_publish_input_type;
pub mod match_3_d_work_snapshot_type;
pub mod match_3_d_work_update_input_type; pub mod match_3_d_work_update_input_type;
pub mod match_3_d_works_list_input_type; pub mod match_3_d_works_list_input_type;
pub mod match_3_d_works_procedure_result_type; pub mod match_3_d_works_procedure_result_type;
@@ -514,58 +499,34 @@ pub mod puzzle_agent_message_finalize_input_type;
pub mod puzzle_agent_message_kind_type; pub mod puzzle_agent_message_kind_type;
pub mod puzzle_agent_message_role_type; pub mod puzzle_agent_message_role_type;
pub mod puzzle_agent_message_row_type; pub mod puzzle_agent_message_row_type;
pub mod puzzle_agent_message_snapshot_type;
pub mod puzzle_agent_message_submit_input_type; pub mod puzzle_agent_message_submit_input_type;
pub mod puzzle_agent_message_table; pub mod puzzle_agent_message_table;
pub mod puzzle_agent_session_create_input_type; pub mod puzzle_agent_session_create_input_type;
pub mod puzzle_agent_session_get_input_type; pub mod puzzle_agent_session_get_input_type;
pub mod puzzle_agent_session_procedure_result_type; pub mod puzzle_agent_session_procedure_result_type;
pub mod puzzle_agent_session_row_type; pub mod puzzle_agent_session_row_type;
pub mod puzzle_agent_session_snapshot_type;
pub mod puzzle_agent_session_table; pub mod puzzle_agent_session_table;
pub mod puzzle_agent_stage_type; pub mod puzzle_agent_stage_type;
pub mod puzzle_agent_suggested_action_type;
pub mod puzzle_anchor_item_type;
pub mod puzzle_anchor_pack_type;
pub mod puzzle_anchor_status_type;
pub mod puzzle_audio_asset_type;
pub mod puzzle_board_snapshot_type;
pub mod puzzle_cell_position_type;
pub mod puzzle_creator_intent_type;
pub mod puzzle_draft_compile_input_type; pub mod puzzle_draft_compile_input_type;
pub mod puzzle_draft_level_type;
pub mod puzzle_event_kind_type; pub mod puzzle_event_kind_type;
pub mod puzzle_event_table; pub mod puzzle_event_table;
pub mod puzzle_event_type; pub mod puzzle_event_type;
pub mod puzzle_form_draft_save_input_type; pub mod puzzle_form_draft_save_input_type;
pub mod puzzle_form_draft_type;
pub mod puzzle_gallery_view_table; pub mod puzzle_gallery_view_table;
pub mod puzzle_generated_image_candidate_type;
pub mod puzzle_generated_images_save_input_type; pub mod puzzle_generated_images_save_input_type;
pub mod puzzle_leaderboard_entry_row_type; pub mod puzzle_leaderboard_entry_row_type;
pub mod puzzle_leaderboard_entry_table; pub mod puzzle_leaderboard_entry_table;
pub mod puzzle_leaderboard_entry_type;
pub mod puzzle_leaderboard_submit_input_type; pub mod puzzle_leaderboard_submit_input_type;
pub mod puzzle_merged_group_state_type;
pub mod puzzle_piece_state_type;
pub mod puzzle_publication_status_type; pub mod puzzle_publication_status_type;
pub mod puzzle_publish_input_type; pub mod puzzle_publish_input_type;
pub mod puzzle_recommended_next_work_type;
pub mod puzzle_result_draft_type;
pub mod puzzle_result_preview_blocker_type;
pub mod puzzle_result_preview_envelope_type;
pub mod puzzle_result_preview_finding_type;
pub mod puzzle_run_drag_input_type; pub mod puzzle_run_drag_input_type;
pub mod puzzle_run_get_input_type; pub mod puzzle_run_get_input_type;
pub mod puzzle_run_next_level_input_type; pub mod puzzle_run_next_level_input_type;
pub mod puzzle_run_pause_input_type; pub mod puzzle_run_pause_input_type;
pub mod puzzle_run_procedure_result_type; pub mod puzzle_run_procedure_result_type;
pub mod puzzle_run_prop_input_type; pub mod puzzle_run_prop_input_type;
pub mod puzzle_run_snapshot_type;
pub mod puzzle_run_start_input_type; pub mod puzzle_run_start_input_type;
pub mod puzzle_run_swap_input_type; pub mod puzzle_run_swap_input_type;
pub mod puzzle_runtime_level_snapshot_type;
pub mod puzzle_runtime_level_status_type;
pub mod puzzle_runtime_run_row_type; pub mod puzzle_runtime_run_row_type;
pub mod puzzle_runtime_run_table; pub mod puzzle_runtime_run_table;
pub mod puzzle_select_cover_image_input_type; pub mod puzzle_select_cover_image_input_type;
@@ -577,7 +538,6 @@ pub mod puzzle_work_point_incentive_claim_input_type;
pub mod puzzle_work_procedure_result_type; pub mod puzzle_work_procedure_result_type;
pub mod puzzle_work_profile_row_type; pub mod puzzle_work_profile_row_type;
pub mod puzzle_work_profile_table; pub mod puzzle_work_profile_table;
pub mod puzzle_work_profile_type;
pub mod puzzle_work_remix_input_type; pub mod puzzle_work_remix_input_type;
pub mod puzzle_work_upsert_input_type; pub mod puzzle_work_upsert_input_type;
pub mod puzzle_works_list_input_type; pub mod puzzle_works_list_input_type;
@@ -769,41 +729,30 @@ pub mod seed_analytics_date_dimensions_reducer;
pub mod select_puzzle_cover_image_procedure; pub mod select_puzzle_cover_image_procedure;
pub mod square_hole_agent_message_finalize_input_type; pub mod square_hole_agent_message_finalize_input_type;
pub mod square_hole_agent_message_row_type; pub mod square_hole_agent_message_row_type;
pub mod square_hole_agent_message_snapshot_type;
pub mod square_hole_agent_message_submit_input_type; pub mod square_hole_agent_message_submit_input_type;
pub mod square_hole_agent_message_table; pub mod square_hole_agent_message_table;
pub mod square_hole_agent_session_create_input_type; pub mod square_hole_agent_session_create_input_type;
pub mod square_hole_agent_session_get_input_type; pub mod square_hole_agent_session_get_input_type;
pub mod square_hole_agent_session_procedure_result_type; pub mod square_hole_agent_session_procedure_result_type;
pub mod square_hole_agent_session_row_type; pub mod square_hole_agent_session_row_type;
pub mod square_hole_agent_session_snapshot_type;
pub mod square_hole_agent_session_table; pub mod square_hole_agent_session_table;
pub mod square_hole_creator_config_snapshot_type;
pub mod square_hole_draft_compile_input_type; pub mod square_hole_draft_compile_input_type;
pub mod square_hole_draft_snapshot_type;
pub mod square_hole_drop_feedback_snapshot_type;
pub mod square_hole_drop_shape_procedure_result_type; pub mod square_hole_drop_shape_procedure_result_type;
pub mod square_hole_hole_option_snapshot_type;
pub mod square_hole_hole_snapshot_type;
pub mod square_hole_run_drop_input_type; pub mod square_hole_run_drop_input_type;
pub mod square_hole_run_get_input_type; pub mod square_hole_run_get_input_type;
pub mod square_hole_run_procedure_result_type; pub mod square_hole_run_procedure_result_type;
pub mod square_hole_run_restart_input_type; pub mod square_hole_run_restart_input_type;
pub mod square_hole_run_snapshot_type;
pub mod square_hole_run_start_input_type; pub mod square_hole_run_start_input_type;
pub mod square_hole_run_stop_input_type; pub mod square_hole_run_stop_input_type;
pub mod square_hole_run_time_up_input_type; pub mod square_hole_run_time_up_input_type;
pub mod square_hole_runtime_run_row_type; pub mod square_hole_runtime_run_row_type;
pub mod square_hole_runtime_run_table; pub mod square_hole_runtime_run_table;
pub mod square_hole_shape_option_snapshot_type;
pub mod square_hole_shape_snapshot_type;
pub mod square_hole_work_delete_input_type; pub mod square_hole_work_delete_input_type;
pub mod square_hole_work_get_input_type; pub mod square_hole_work_get_input_type;
pub mod square_hole_work_procedure_result_type; pub mod square_hole_work_procedure_result_type;
pub mod square_hole_work_profile_row_type; pub mod square_hole_work_profile_row_type;
pub mod square_hole_work_profile_table; pub mod square_hole_work_profile_table;
pub mod square_hole_work_publish_input_type; pub mod square_hole_work_publish_input_type;
pub mod square_hole_work_snapshot_type;
pub mod square_hole_work_update_input_type; pub mod square_hole_work_update_input_type;
pub mod square_hole_works_list_input_type; pub mod square_hole_works_list_input_type;
pub mod square_hole_works_procedure_result_type; pub mod square_hole_works_procedure_result_type;
@@ -880,31 +829,24 @@ pub mod user_browse_history_table;
pub mod user_browse_history_type; pub mod user_browse_history_type;
pub mod visual_novel_agent_message_finalize_input_type; pub mod visual_novel_agent_message_finalize_input_type;
pub mod visual_novel_agent_message_row_type; pub mod visual_novel_agent_message_row_type;
pub mod visual_novel_agent_message_snapshot_type;
pub mod visual_novel_agent_message_submit_input_type; pub mod visual_novel_agent_message_submit_input_type;
pub mod visual_novel_agent_message_table; pub mod visual_novel_agent_message_table;
pub mod visual_novel_agent_session_create_input_type; pub mod visual_novel_agent_session_create_input_type;
pub mod visual_novel_agent_session_get_input_type; pub mod visual_novel_agent_session_get_input_type;
pub mod visual_novel_agent_session_procedure_result_type; pub mod visual_novel_agent_session_procedure_result_type;
pub mod visual_novel_agent_session_row_type; pub mod visual_novel_agent_session_row_type;
pub mod visual_novel_agent_session_snapshot_type;
pub mod visual_novel_agent_session_table; pub mod visual_novel_agent_session_table;
pub mod visual_novel_history_procedure_result_type; pub mod visual_novel_history_procedure_result_type;
pub mod visual_novel_json_field_type;
pub mod visual_novel_json_value_type;
pub mod visual_novel_run_get_input_type; pub mod visual_novel_run_get_input_type;
pub mod visual_novel_run_procedure_result_type; pub mod visual_novel_run_procedure_result_type;
pub mod visual_novel_run_snapshot_type;
pub mod visual_novel_run_snapshot_upsert_input_type; pub mod visual_novel_run_snapshot_upsert_input_type;
pub mod visual_novel_run_start_input_type; pub mod visual_novel_run_start_input_type;
pub mod visual_novel_runtime_event_procedure_result_type; pub mod visual_novel_runtime_event_procedure_result_type;
pub mod visual_novel_runtime_event_record_input_type; pub mod visual_novel_runtime_event_record_input_type;
pub mod visual_novel_runtime_event_snapshot_type;
pub mod visual_novel_runtime_event_table; pub mod visual_novel_runtime_event_table;
pub mod visual_novel_runtime_event_type; pub mod visual_novel_runtime_event_type;
pub mod visual_novel_runtime_history_append_input_type; pub mod visual_novel_runtime_history_append_input_type;
pub mod visual_novel_runtime_history_entry_row_type; pub mod visual_novel_runtime_history_entry_row_type;
pub mod visual_novel_runtime_history_entry_snapshot_type;
pub mod visual_novel_runtime_history_entry_table; pub mod visual_novel_runtime_history_entry_table;
pub mod visual_novel_runtime_history_list_input_type; pub mod visual_novel_runtime_history_list_input_type;
pub mod visual_novel_runtime_run_row_type; pub mod visual_novel_runtime_run_row_type;
@@ -916,7 +858,6 @@ pub mod visual_novel_work_procedure_result_type;
pub mod visual_novel_work_profile_row_type; pub mod visual_novel_work_profile_row_type;
pub mod visual_novel_work_profile_table; pub mod visual_novel_work_profile_table;
pub mod visual_novel_work_publish_input_type; pub mod visual_novel_work_publish_input_type;
pub mod visual_novel_work_snapshot_type;
pub mod visual_novel_work_update_input_type; pub mod visual_novel_work_update_input_type;
pub mod visual_novel_works_list_input_type; pub mod visual_novel_works_list_input_type;
pub mod visual_novel_works_procedure_result_type; pub mod visual_novel_works_procedure_result_type;
@@ -1010,7 +951,6 @@ pub use auth_store_snapshot_type::AuthStoreSnapshot;
pub use auth_store_snapshot_upsert_input_type::AuthStoreSnapshotUpsertInput; pub use auth_store_snapshot_upsert_input_type::AuthStoreSnapshotUpsertInput;
pub use authorize_database_migration_operator_procedure::authorize_database_migration_operator; pub use authorize_database_migration_operator_procedure::authorize_database_migration_operator;
pub use bark_battle_draft_config_row_type::BarkBattleDraftConfigRow; pub use bark_battle_draft_config_row_type::BarkBattleDraftConfigRow;
pub use bark_battle_draft_config_snapshot_type::BarkBattleDraftConfigSnapshot;
pub use bark_battle_draft_config_table::*; pub use bark_battle_draft_config_table::*;
pub use bark_battle_draft_config_upsert_input_type::BarkBattleDraftConfigUpsertInput; pub use bark_battle_draft_config_upsert_input_type::BarkBattleDraftConfigUpsertInput;
pub use bark_battle_draft_create_input_type::BarkBattleDraftCreateInput; pub use bark_battle_draft_create_input_type::BarkBattleDraftCreateInput;
@@ -1023,10 +963,8 @@ pub use bark_battle_published_config_row_type::BarkBattlePublishedConfigRow;
pub use bark_battle_published_config_table::*; pub use bark_battle_published_config_table::*;
pub use bark_battle_run_finish_input_type::BarkBattleRunFinishInput; pub use bark_battle_run_finish_input_type::BarkBattleRunFinishInput;
pub use bark_battle_run_get_input_type::BarkBattleRunGetInput; pub use bark_battle_run_get_input_type::BarkBattleRunGetInput;
pub use bark_battle_run_snapshot_type::BarkBattleRunSnapshot;
pub use bark_battle_run_start_input_type::BarkBattleRunStartInput; pub use bark_battle_run_start_input_type::BarkBattleRunStartInput;
pub use bark_battle_runtime_config_get_input_type::BarkBattleRuntimeConfigGetInput; pub use bark_battle_runtime_config_get_input_type::BarkBattleRuntimeConfigGetInput;
pub use bark_battle_runtime_config_snapshot_type::BarkBattleRuntimeConfigSnapshot;
pub use bark_battle_runtime_run_row_type::BarkBattleRuntimeRunRow; pub use bark_battle_runtime_run_row_type::BarkBattleRuntimeRunRow;
pub use bark_battle_runtime_run_table::*; pub use bark_battle_runtime_run_table::*;
pub use bark_battle_score_record_row_type::BarkBattleScoreRecordRow; pub use bark_battle_score_record_row_type::BarkBattleScoreRecordRow;
@@ -1078,20 +1016,16 @@ pub use big_fish_run_get_input_type::BigFishRunGetInput;
pub use big_fish_run_procedure_result_type::BigFishRunProcedureResult; pub use big_fish_run_procedure_result_type::BigFishRunProcedureResult;
pub use big_fish_run_start_input_type::BigFishRunStartInput; pub use big_fish_run_start_input_type::BigFishRunStartInput;
pub use big_fish_run_status_type::BigFishRunStatus; pub use big_fish_run_status_type::BigFishRunStatus;
pub use big_fish_runtime_entity_snapshot_type::BigFishRuntimeEntitySnapshot;
pub use big_fish_runtime_params_type::BigFishRuntimeParams; pub use big_fish_runtime_params_type::BigFishRuntimeParams;
pub use big_fish_runtime_run_table::*; pub use big_fish_runtime_run_table::*;
pub use big_fish_runtime_run_type::BigFishRuntimeRun; pub use big_fish_runtime_run_type::BigFishRuntimeRun;
pub use big_fish_runtime_snapshot_type::BigFishRuntimeSnapshot;
pub use big_fish_session_create_input_type::BigFishSessionCreateInput; pub use big_fish_session_create_input_type::BigFishSessionCreateInput;
pub use big_fish_session_get_input_type::BigFishSessionGetInput; pub use big_fish_session_get_input_type::BigFishSessionGetInput;
pub use big_fish_session_procedure_result_type::BigFishSessionProcedureResult; pub use big_fish_session_procedure_result_type::BigFishSessionProcedureResult;
pub use big_fish_session_snapshot_type::BigFishSessionSnapshot; pub use big_fish_session_snapshot_type::BigFishSessionSnapshot;
pub use big_fish_vector_2_type::BigFishVector2;
pub use big_fish_work_delete_input_type::BigFishWorkDeleteInput; pub use big_fish_work_delete_input_type::BigFishWorkDeleteInput;
pub use big_fish_work_like_record_input_type::BigFishWorkLikeRecordInput; pub use big_fish_work_like_record_input_type::BigFishWorkLikeRecordInput;
pub use big_fish_work_remix_input_type::BigFishWorkRemixInput; pub use big_fish_work_remix_input_type::BigFishWorkRemixInput;
pub use big_fish_work_summary_snapshot_type::BigFishWorkSummarySnapshot;
pub use big_fish_works_list_input_type::BigFishWorksListInput; pub use big_fish_works_list_input_type::BigFishWorksListInput;
pub use big_fish_works_procedure_result_type::BigFishWorksProcedureResult; pub use big_fish_works_procedure_result_type::BigFishWorksProcedureResult;
pub use bind_asset_object_to_entity_and_return_procedure::bind_asset_object_to_entity_and_return; pub use bind_asset_object_to_entity_and_return_procedure::bind_asset_object_to_entity_and_return;
@@ -1324,38 +1258,30 @@ pub use list_visual_novel_works_procedure::list_visual_novel_works;
pub use mark_profile_recharge_order_paid_and_return_procedure::mark_profile_recharge_order_paid_and_return; 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_finalize_input_type::Match3DAgentMessageFinalizeInput;
pub use match_3_d_agent_message_row_type::Match3DAgentMessageRow; pub use match_3_d_agent_message_row_type::Match3DAgentMessageRow;
pub use match_3_d_agent_message_snapshot_type::Match3DAgentMessageSnapshot;
pub use match_3_d_agent_message_submit_input_type::Match3DAgentMessageSubmitInput; pub use match_3_d_agent_message_submit_input_type::Match3DAgentMessageSubmitInput;
pub use match_3_d_agent_message_table::*; pub use match_3_d_agent_message_table::*;
pub use match_3_d_agent_session_create_input_type::Match3DAgentSessionCreateInput; pub use match_3_d_agent_session_create_input_type::Match3DAgentSessionCreateInput;
pub use match_3_d_agent_session_get_input_type::Match3DAgentSessionGetInput; pub use match_3_d_agent_session_get_input_type::Match3DAgentSessionGetInput;
pub use match_3_d_agent_session_procedure_result_type::Match3DAgentSessionProcedureResult; pub use match_3_d_agent_session_procedure_result_type::Match3DAgentSessionProcedureResult;
pub use match_3_d_agent_session_row_type::Match3DAgentSessionRow; pub use match_3_d_agent_session_row_type::Match3DAgentSessionRow;
pub use match_3_d_agent_session_snapshot_type::Match3DAgentSessionSnapshot;
pub use match_3_d_agent_session_table::*; pub use match_3_d_agent_session_table::*;
pub use match_3_d_click_item_procedure_result_type::Match3DClickItemProcedureResult; pub use match_3_d_click_item_procedure_result_type::Match3DClickItemProcedureResult;
pub use match_3_d_creator_config_snapshot_type::Match3DCreatorConfigSnapshot;
pub use match_3_d_draft_compile_input_type::Match3DDraftCompileInput; pub use match_3_d_draft_compile_input_type::Match3DDraftCompileInput;
pub use match_3_d_draft_snapshot_type::Match3DDraftSnapshot;
pub use match_3_d_item_snapshot_type::Match3DItemSnapshot;
pub use match_3_d_run_click_input_type::Match3DRunClickInput; pub use match_3_d_run_click_input_type::Match3DRunClickInput;
pub use match_3_d_run_get_input_type::Match3DRunGetInput; pub use match_3_d_run_get_input_type::Match3DRunGetInput;
pub use match_3_d_run_procedure_result_type::Match3DRunProcedureResult; pub use match_3_d_run_procedure_result_type::Match3DRunProcedureResult;
pub use match_3_d_run_restart_input_type::Match3DRunRestartInput; pub use match_3_d_run_restart_input_type::Match3DRunRestartInput;
pub use match_3_d_run_snapshot_type::Match3DRunSnapshot;
pub use match_3_d_run_start_input_type::Match3DRunStartInput; pub use match_3_d_run_start_input_type::Match3DRunStartInput;
pub use match_3_d_run_stop_input_type::Match3DRunStopInput; pub use match_3_d_run_stop_input_type::Match3DRunStopInput;
pub use match_3_d_run_time_up_input_type::Match3DRunTimeUpInput; pub use match_3_d_run_time_up_input_type::Match3DRunTimeUpInput;
pub use match_3_d_runtime_run_row_type::Match3DRuntimeRunRow; pub use match_3_d_runtime_run_row_type::Match3DRuntimeRunRow;
pub use match_3_d_runtime_run_table::*; pub use match_3_d_runtime_run_table::*;
pub use match_3_d_tray_slot_snapshot_type::Match3DTraySlotSnapshot;
pub use match_3_d_work_delete_input_type::Match3DWorkDeleteInput; pub use match_3_d_work_delete_input_type::Match3DWorkDeleteInput;
pub use match_3_d_work_get_input_type::Match3DWorkGetInput; pub use match_3_d_work_get_input_type::Match3DWorkGetInput;
pub use match_3_d_work_procedure_result_type::Match3DWorkProcedureResult; pub use match_3_d_work_procedure_result_type::Match3DWorkProcedureResult;
pub use match_3_d_work_profile_row_type::Match3DWorkProfileRow; pub use match_3_d_work_profile_row_type::Match3DWorkProfileRow;
pub use match_3_d_work_profile_table::*; pub use match_3_d_work_profile_table::*;
pub use match_3_d_work_publish_input_type::Match3DWorkPublishInput; pub use match_3_d_work_publish_input_type::Match3DWorkPublishInput;
pub use match_3_d_work_snapshot_type::Match3DWorkSnapshot;
pub use match_3_d_work_update_input_type::Match3DWorkUpdateInput; pub use match_3_d_work_update_input_type::Match3DWorkUpdateInput;
pub use match_3_d_works_list_input_type::Match3DWorksListInput; pub use match_3_d_works_list_input_type::Match3DWorksListInput;
pub use match_3_d_works_procedure_result_type::Match3DWorksProcedureResult; pub use match_3_d_works_procedure_result_type::Match3DWorksProcedureResult;
@@ -1429,58 +1355,34 @@ pub use puzzle_agent_message_finalize_input_type::PuzzleAgentMessageFinalizeInpu
pub use puzzle_agent_message_kind_type::PuzzleAgentMessageKind; pub use puzzle_agent_message_kind_type::PuzzleAgentMessageKind;
pub use puzzle_agent_message_role_type::PuzzleAgentMessageRole; pub use puzzle_agent_message_role_type::PuzzleAgentMessageRole;
pub use puzzle_agent_message_row_type::PuzzleAgentMessageRow; pub use puzzle_agent_message_row_type::PuzzleAgentMessageRow;
pub use puzzle_agent_message_snapshot_type::PuzzleAgentMessageSnapshot;
pub use puzzle_agent_message_submit_input_type::PuzzleAgentMessageSubmitInput; pub use puzzle_agent_message_submit_input_type::PuzzleAgentMessageSubmitInput;
pub use puzzle_agent_message_table::*; pub use puzzle_agent_message_table::*;
pub use puzzle_agent_session_create_input_type::PuzzleAgentSessionCreateInput; pub use puzzle_agent_session_create_input_type::PuzzleAgentSessionCreateInput;
pub use puzzle_agent_session_get_input_type::PuzzleAgentSessionGetInput; pub use puzzle_agent_session_get_input_type::PuzzleAgentSessionGetInput;
pub use puzzle_agent_session_procedure_result_type::PuzzleAgentSessionProcedureResult; pub use puzzle_agent_session_procedure_result_type::PuzzleAgentSessionProcedureResult;
pub use puzzle_agent_session_row_type::PuzzleAgentSessionRow; pub use puzzle_agent_session_row_type::PuzzleAgentSessionRow;
pub use puzzle_agent_session_snapshot_type::PuzzleAgentSessionSnapshot;
pub use puzzle_agent_session_table::*; pub use puzzle_agent_session_table::*;
pub use puzzle_agent_stage_type::PuzzleAgentStage; pub use puzzle_agent_stage_type::PuzzleAgentStage;
pub use puzzle_agent_suggested_action_type::PuzzleAgentSuggestedAction;
pub use puzzle_anchor_item_type::PuzzleAnchorItem;
pub use puzzle_anchor_pack_type::PuzzleAnchorPack;
pub use puzzle_anchor_status_type::PuzzleAnchorStatus;
pub use puzzle_audio_asset_type::PuzzleAudioAsset;
pub use puzzle_board_snapshot_type::PuzzleBoardSnapshot;
pub use puzzle_cell_position_type::PuzzleCellPosition;
pub use puzzle_creator_intent_type::PuzzleCreatorIntent;
pub use puzzle_draft_compile_input_type::PuzzleDraftCompileInput; pub use puzzle_draft_compile_input_type::PuzzleDraftCompileInput;
pub use puzzle_draft_level_type::PuzzleDraftLevel;
pub use puzzle_event_kind_type::PuzzleEventKind; pub use puzzle_event_kind_type::PuzzleEventKind;
pub use puzzle_event_table::*; pub use puzzle_event_table::*;
pub use puzzle_event_type::PuzzleEvent; pub use puzzle_event_type::PuzzleEvent;
pub use puzzle_form_draft_save_input_type::PuzzleFormDraftSaveInput; pub use puzzle_form_draft_save_input_type::PuzzleFormDraftSaveInput;
pub use puzzle_form_draft_type::PuzzleFormDraft;
pub use puzzle_gallery_view_table::*; pub use puzzle_gallery_view_table::*;
pub use puzzle_generated_image_candidate_type::PuzzleGeneratedImageCandidate;
pub use puzzle_generated_images_save_input_type::PuzzleGeneratedImagesSaveInput; pub use puzzle_generated_images_save_input_type::PuzzleGeneratedImagesSaveInput;
pub use puzzle_leaderboard_entry_row_type::PuzzleLeaderboardEntryRow; pub use puzzle_leaderboard_entry_row_type::PuzzleLeaderboardEntryRow;
pub use puzzle_leaderboard_entry_table::*; pub use puzzle_leaderboard_entry_table::*;
pub use puzzle_leaderboard_entry_type::PuzzleLeaderboardEntry;
pub use puzzle_leaderboard_submit_input_type::PuzzleLeaderboardSubmitInput; pub use puzzle_leaderboard_submit_input_type::PuzzleLeaderboardSubmitInput;
pub use puzzle_merged_group_state_type::PuzzleMergedGroupState;
pub use puzzle_piece_state_type::PuzzlePieceState;
pub use puzzle_publication_status_type::PuzzlePublicationStatus; pub use puzzle_publication_status_type::PuzzlePublicationStatus;
pub use puzzle_publish_input_type::PuzzlePublishInput; pub use puzzle_publish_input_type::PuzzlePublishInput;
pub use puzzle_recommended_next_work_type::PuzzleRecommendedNextWork;
pub use puzzle_result_draft_type::PuzzleResultDraft;
pub use puzzle_result_preview_blocker_type::PuzzleResultPreviewBlocker;
pub use puzzle_result_preview_envelope_type::PuzzleResultPreviewEnvelope;
pub use puzzle_result_preview_finding_type::PuzzleResultPreviewFinding;
pub use puzzle_run_drag_input_type::PuzzleRunDragInput; pub use puzzle_run_drag_input_type::PuzzleRunDragInput;
pub use puzzle_run_get_input_type::PuzzleRunGetInput; pub use puzzle_run_get_input_type::PuzzleRunGetInput;
pub use puzzle_run_next_level_input_type::PuzzleRunNextLevelInput; pub use puzzle_run_next_level_input_type::PuzzleRunNextLevelInput;
pub use puzzle_run_pause_input_type::PuzzleRunPauseInput; pub use puzzle_run_pause_input_type::PuzzleRunPauseInput;
pub use puzzle_run_procedure_result_type::PuzzleRunProcedureResult; pub use puzzle_run_procedure_result_type::PuzzleRunProcedureResult;
pub use puzzle_run_prop_input_type::PuzzleRunPropInput; pub use puzzle_run_prop_input_type::PuzzleRunPropInput;
pub use puzzle_run_snapshot_type::PuzzleRunSnapshot;
pub use puzzle_run_start_input_type::PuzzleRunStartInput; pub use puzzle_run_start_input_type::PuzzleRunStartInput;
pub use puzzle_run_swap_input_type::PuzzleRunSwapInput; pub use puzzle_run_swap_input_type::PuzzleRunSwapInput;
pub use puzzle_runtime_level_snapshot_type::PuzzleRuntimeLevelSnapshot;
pub use puzzle_runtime_level_status_type::PuzzleRuntimeLevelStatus;
pub use puzzle_runtime_run_row_type::PuzzleRuntimeRunRow; pub use puzzle_runtime_run_row_type::PuzzleRuntimeRunRow;
pub use puzzle_runtime_run_table::*; pub use puzzle_runtime_run_table::*;
pub use puzzle_select_cover_image_input_type::PuzzleSelectCoverImageInput; pub use puzzle_select_cover_image_input_type::PuzzleSelectCoverImageInput;
@@ -1492,7 +1394,6 @@ pub use puzzle_work_point_incentive_claim_input_type::PuzzleWorkPointIncentiveCl
pub use puzzle_work_procedure_result_type::PuzzleWorkProcedureResult; pub use puzzle_work_procedure_result_type::PuzzleWorkProcedureResult;
pub use puzzle_work_profile_row_type::PuzzleWorkProfileRow; pub use puzzle_work_profile_row_type::PuzzleWorkProfileRow;
pub use puzzle_work_profile_table::*; pub use puzzle_work_profile_table::*;
pub use puzzle_work_profile_type::PuzzleWorkProfile;
pub use puzzle_work_remix_input_type::PuzzleWorkRemixInput; pub use puzzle_work_remix_input_type::PuzzleWorkRemixInput;
pub use puzzle_work_upsert_input_type::PuzzleWorkUpsertInput; pub use puzzle_work_upsert_input_type::PuzzleWorkUpsertInput;
pub use puzzle_works_list_input_type::PuzzleWorksListInput; pub use puzzle_works_list_input_type::PuzzleWorksListInput;
@@ -1684,41 +1585,30 @@ pub use seed_analytics_date_dimensions_reducer::seed_analytics_date_dimensions;
pub use select_puzzle_cover_image_procedure::select_puzzle_cover_image; pub use select_puzzle_cover_image_procedure::select_puzzle_cover_image;
pub use square_hole_agent_message_finalize_input_type::SquareHoleAgentMessageFinalizeInput; pub use square_hole_agent_message_finalize_input_type::SquareHoleAgentMessageFinalizeInput;
pub use square_hole_agent_message_row_type::SquareHoleAgentMessageRow; pub use square_hole_agent_message_row_type::SquareHoleAgentMessageRow;
pub use square_hole_agent_message_snapshot_type::SquareHoleAgentMessageSnapshot;
pub use square_hole_agent_message_submit_input_type::SquareHoleAgentMessageSubmitInput; pub use square_hole_agent_message_submit_input_type::SquareHoleAgentMessageSubmitInput;
pub use square_hole_agent_message_table::*; pub use square_hole_agent_message_table::*;
pub use square_hole_agent_session_create_input_type::SquareHoleAgentSessionCreateInput; pub use square_hole_agent_session_create_input_type::SquareHoleAgentSessionCreateInput;
pub use square_hole_agent_session_get_input_type::SquareHoleAgentSessionGetInput; pub use square_hole_agent_session_get_input_type::SquareHoleAgentSessionGetInput;
pub use square_hole_agent_session_procedure_result_type::SquareHoleAgentSessionProcedureResult; pub use square_hole_agent_session_procedure_result_type::SquareHoleAgentSessionProcedureResult;
pub use square_hole_agent_session_row_type::SquareHoleAgentSessionRow; pub use square_hole_agent_session_row_type::SquareHoleAgentSessionRow;
pub use square_hole_agent_session_snapshot_type::SquareHoleAgentSessionSnapshot;
pub use square_hole_agent_session_table::*; pub use square_hole_agent_session_table::*;
pub use square_hole_creator_config_snapshot_type::SquareHoleCreatorConfigSnapshot;
pub use square_hole_draft_compile_input_type::SquareHoleDraftCompileInput; pub use square_hole_draft_compile_input_type::SquareHoleDraftCompileInput;
pub use square_hole_draft_snapshot_type::SquareHoleDraftSnapshot;
pub use square_hole_drop_feedback_snapshot_type::SquareHoleDropFeedbackSnapshot;
pub use square_hole_drop_shape_procedure_result_type::SquareHoleDropShapeProcedureResult; pub use square_hole_drop_shape_procedure_result_type::SquareHoleDropShapeProcedureResult;
pub use square_hole_hole_option_snapshot_type::SquareHoleHoleOptionSnapshot;
pub use square_hole_hole_snapshot_type::SquareHoleHoleSnapshot;
pub use square_hole_run_drop_input_type::SquareHoleRunDropInput; pub use square_hole_run_drop_input_type::SquareHoleRunDropInput;
pub use square_hole_run_get_input_type::SquareHoleRunGetInput; pub use square_hole_run_get_input_type::SquareHoleRunGetInput;
pub use square_hole_run_procedure_result_type::SquareHoleRunProcedureResult; pub use square_hole_run_procedure_result_type::SquareHoleRunProcedureResult;
pub use square_hole_run_restart_input_type::SquareHoleRunRestartInput; pub use square_hole_run_restart_input_type::SquareHoleRunRestartInput;
pub use square_hole_run_snapshot_type::SquareHoleRunSnapshot;
pub use square_hole_run_start_input_type::SquareHoleRunStartInput; pub use square_hole_run_start_input_type::SquareHoleRunStartInput;
pub use square_hole_run_stop_input_type::SquareHoleRunStopInput; pub use square_hole_run_stop_input_type::SquareHoleRunStopInput;
pub use square_hole_run_time_up_input_type::SquareHoleRunTimeUpInput; pub use square_hole_run_time_up_input_type::SquareHoleRunTimeUpInput;
pub use square_hole_runtime_run_row_type::SquareHoleRuntimeRunRow; pub use square_hole_runtime_run_row_type::SquareHoleRuntimeRunRow;
pub use square_hole_runtime_run_table::*; pub use square_hole_runtime_run_table::*;
pub use square_hole_shape_option_snapshot_type::SquareHoleShapeOptionSnapshot;
pub use square_hole_shape_snapshot_type::SquareHoleShapeSnapshot;
pub use square_hole_work_delete_input_type::SquareHoleWorkDeleteInput; pub use square_hole_work_delete_input_type::SquareHoleWorkDeleteInput;
pub use square_hole_work_get_input_type::SquareHoleWorkGetInput; pub use square_hole_work_get_input_type::SquareHoleWorkGetInput;
pub use square_hole_work_procedure_result_type::SquareHoleWorkProcedureResult; pub use square_hole_work_procedure_result_type::SquareHoleWorkProcedureResult;
pub use square_hole_work_profile_row_type::SquareHoleWorkProfileRow; pub use square_hole_work_profile_row_type::SquareHoleWorkProfileRow;
pub use square_hole_work_profile_table::*; pub use square_hole_work_profile_table::*;
pub use square_hole_work_publish_input_type::SquareHoleWorkPublishInput; pub use square_hole_work_publish_input_type::SquareHoleWorkPublishInput;
pub use square_hole_work_snapshot_type::SquareHoleWorkSnapshot;
pub use square_hole_work_update_input_type::SquareHoleWorkUpdateInput; pub use square_hole_work_update_input_type::SquareHoleWorkUpdateInput;
pub use square_hole_works_list_input_type::SquareHoleWorksListInput; pub use square_hole_works_list_input_type::SquareHoleWorksListInput;
pub use square_hole_works_procedure_result_type::SquareHoleWorksProcedureResult; pub use square_hole_works_procedure_result_type::SquareHoleWorksProcedureResult;
@@ -1795,31 +1685,24 @@ pub use user_browse_history_table::*;
pub use user_browse_history_type::UserBrowseHistory; pub use user_browse_history_type::UserBrowseHistory;
pub use visual_novel_agent_message_finalize_input_type::VisualNovelAgentMessageFinalizeInput; pub use visual_novel_agent_message_finalize_input_type::VisualNovelAgentMessageFinalizeInput;
pub use visual_novel_agent_message_row_type::VisualNovelAgentMessageRow; pub use visual_novel_agent_message_row_type::VisualNovelAgentMessageRow;
pub use visual_novel_agent_message_snapshot_type::VisualNovelAgentMessageSnapshot;
pub use visual_novel_agent_message_submit_input_type::VisualNovelAgentMessageSubmitInput; pub use visual_novel_agent_message_submit_input_type::VisualNovelAgentMessageSubmitInput;
pub use visual_novel_agent_message_table::*; pub use visual_novel_agent_message_table::*;
pub use visual_novel_agent_session_create_input_type::VisualNovelAgentSessionCreateInput; pub use visual_novel_agent_session_create_input_type::VisualNovelAgentSessionCreateInput;
pub use visual_novel_agent_session_get_input_type::VisualNovelAgentSessionGetInput; pub use visual_novel_agent_session_get_input_type::VisualNovelAgentSessionGetInput;
pub use visual_novel_agent_session_procedure_result_type::VisualNovelAgentSessionProcedureResult; pub use visual_novel_agent_session_procedure_result_type::VisualNovelAgentSessionProcedureResult;
pub use visual_novel_agent_session_row_type::VisualNovelAgentSessionRow; pub use visual_novel_agent_session_row_type::VisualNovelAgentSessionRow;
pub use visual_novel_agent_session_snapshot_type::VisualNovelAgentSessionSnapshot;
pub use visual_novel_agent_session_table::*; pub use visual_novel_agent_session_table::*;
pub use visual_novel_history_procedure_result_type::VisualNovelHistoryProcedureResult; pub use visual_novel_history_procedure_result_type::VisualNovelHistoryProcedureResult;
pub use visual_novel_json_field_type::VisualNovelJsonField;
pub use visual_novel_json_value_type::VisualNovelJsonValue;
pub use visual_novel_run_get_input_type::VisualNovelRunGetInput; pub use visual_novel_run_get_input_type::VisualNovelRunGetInput;
pub use visual_novel_run_procedure_result_type::VisualNovelRunProcedureResult; pub use visual_novel_run_procedure_result_type::VisualNovelRunProcedureResult;
pub use visual_novel_run_snapshot_type::VisualNovelRunSnapshot;
pub use visual_novel_run_snapshot_upsert_input_type::VisualNovelRunSnapshotUpsertInput; pub use visual_novel_run_snapshot_upsert_input_type::VisualNovelRunSnapshotUpsertInput;
pub use visual_novel_run_start_input_type::VisualNovelRunStartInput; pub use visual_novel_run_start_input_type::VisualNovelRunStartInput;
pub use visual_novel_runtime_event_procedure_result_type::VisualNovelRuntimeEventProcedureResult; pub use visual_novel_runtime_event_procedure_result_type::VisualNovelRuntimeEventProcedureResult;
pub use visual_novel_runtime_event_record_input_type::VisualNovelRuntimeEventRecordInput; pub use visual_novel_runtime_event_record_input_type::VisualNovelRuntimeEventRecordInput;
pub use visual_novel_runtime_event_snapshot_type::VisualNovelRuntimeEventSnapshot;
pub use visual_novel_runtime_event_table::*; pub use visual_novel_runtime_event_table::*;
pub use visual_novel_runtime_event_type::VisualNovelRuntimeEvent; pub use visual_novel_runtime_event_type::VisualNovelRuntimeEvent;
pub use visual_novel_runtime_history_append_input_type::VisualNovelRuntimeHistoryAppendInput; pub use visual_novel_runtime_history_append_input_type::VisualNovelRuntimeHistoryAppendInput;
pub use visual_novel_runtime_history_entry_row_type::VisualNovelRuntimeHistoryEntryRow; pub use visual_novel_runtime_history_entry_row_type::VisualNovelRuntimeHistoryEntryRow;
pub use visual_novel_runtime_history_entry_snapshot_type::VisualNovelRuntimeHistoryEntrySnapshot;
pub use visual_novel_runtime_history_entry_table::*; pub use visual_novel_runtime_history_entry_table::*;
pub use visual_novel_runtime_history_list_input_type::VisualNovelRuntimeHistoryListInput; pub use visual_novel_runtime_history_list_input_type::VisualNovelRuntimeHistoryListInput;
pub use visual_novel_runtime_run_row_type::VisualNovelRuntimeRunRow; pub use visual_novel_runtime_run_row_type::VisualNovelRuntimeRunRow;
@@ -1831,7 +1714,6 @@ pub use visual_novel_work_procedure_result_type::VisualNovelWorkProcedureResult;
pub use visual_novel_work_profile_row_type::VisualNovelWorkProfileRow; pub use visual_novel_work_profile_row_type::VisualNovelWorkProfileRow;
pub use visual_novel_work_profile_table::*; pub use visual_novel_work_profile_table::*;
pub use visual_novel_work_publish_input_type::VisualNovelWorkPublishInput; pub use visual_novel_work_publish_input_type::VisualNovelWorkPublishInput;
pub use visual_novel_work_snapshot_type::VisualNovelWorkSnapshot;
pub use visual_novel_work_update_input_type::VisualNovelWorkUpdateInput; pub use visual_novel_work_update_input_type::VisualNovelWorkUpdateInput;
pub use visual_novel_works_list_input_type::VisualNovelWorksListInput; pub use visual_novel_works_list_input_type::VisualNovelWorksListInput;
pub use visual_novel_works_procedure_result_type::VisualNovelWorksProcedureResult; pub use visual_novel_works_procedure_result_type::VisualNovelWorksProcedureResult;
@@ -2172,7 +2054,7 @@ pub struct DbUpdate {
puzzle_agent_message: __sdk::TableUpdate<PuzzleAgentMessageRow>, puzzle_agent_message: __sdk::TableUpdate<PuzzleAgentMessageRow>,
puzzle_agent_session: __sdk::TableUpdate<PuzzleAgentSessionRow>, puzzle_agent_session: __sdk::TableUpdate<PuzzleAgentSessionRow>,
puzzle_event: __sdk::TableUpdate<PuzzleEvent>, puzzle_event: __sdk::TableUpdate<PuzzleEvent>,
puzzle_gallery_view: __sdk::TableUpdate<PuzzleWorkProfile>, puzzle_gallery_view: __sdk::TableUpdate<PuzzleGalleryViewRow>,
puzzle_leaderboard_entry: __sdk::TableUpdate<PuzzleLeaderboardEntryRow>, puzzle_leaderboard_entry: __sdk::TableUpdate<PuzzleLeaderboardEntryRow>,
puzzle_runtime_run: __sdk::TableUpdate<PuzzleRuntimeRunRow>, puzzle_runtime_run: __sdk::TableUpdate<PuzzleRuntimeRunRow>,
puzzle_work_profile: __sdk::TableUpdate<PuzzleWorkProfileRow>, puzzle_work_profile: __sdk::TableUpdate<PuzzleWorkProfileRow>,
@@ -2966,7 +2848,7 @@ impl __sdk::DbUpdate for DbUpdate {
&self.visual_novel_work_profile, &self.visual_novel_work_profile,
) )
.with_updates_by_pk(|row| &row.profile_id); .with_updates_by_pk(|row| &row.profile_id);
diff.puzzle_gallery_view = cache.apply_diff_to_table::<PuzzleWorkProfile>( diff.puzzle_gallery_view = cache.apply_diff_to_table::<PuzzleGalleryViewRow>(
"puzzle_gallery_view", "puzzle_gallery_view",
&self.puzzle_gallery_view, &self.puzzle_gallery_view,
); );
@@ -3611,7 +3493,7 @@ pub struct AppliedDiff<'r> {
puzzle_agent_message: __sdk::TableAppliedDiff<'r, PuzzleAgentMessageRow>, puzzle_agent_message: __sdk::TableAppliedDiff<'r, PuzzleAgentMessageRow>,
puzzle_agent_session: __sdk::TableAppliedDiff<'r, PuzzleAgentSessionRow>, puzzle_agent_session: __sdk::TableAppliedDiff<'r, PuzzleAgentSessionRow>,
puzzle_event: __sdk::TableAppliedDiff<'r, PuzzleEvent>, puzzle_event: __sdk::TableAppliedDiff<'r, PuzzleEvent>,
puzzle_gallery_view: __sdk::TableAppliedDiff<'r, PuzzleWorkProfile>, puzzle_gallery_view: __sdk::TableAppliedDiff<'r, PuzzleGalleryViewRow>,
puzzle_leaderboard_entry: __sdk::TableAppliedDiff<'r, PuzzleLeaderboardEntryRow>, puzzle_leaderboard_entry: __sdk::TableAppliedDiff<'r, PuzzleLeaderboardEntryRow>,
puzzle_runtime_run: __sdk::TableAppliedDiff<'r, PuzzleRuntimeRunRow>, puzzle_runtime_run: __sdk::TableAppliedDiff<'r, PuzzleRuntimeRunRow>,
puzzle_work_profile: __sdk::TableAppliedDiff<'r, PuzzleWorkProfileRow>, puzzle_work_profile: __sdk::TableAppliedDiff<'r, PuzzleWorkProfileRow>,
@@ -3959,7 +3841,7 @@ impl<'r> __sdk::AppliedDiff<'r> for AppliedDiff<'r> {
&self.puzzle_event, &self.puzzle_event,
event, event,
); );
callbacks.invoke_table_row_callbacks::<PuzzleWorkProfile>( callbacks.invoke_table_row_callbacks::<PuzzleGalleryViewRow>(
"puzzle_gallery_view", "puzzle_gallery_view",
&self.puzzle_gallery_view, &self.puzzle_gallery_view,
event, event,

View File

@@ -2,12 +2,246 @@
// WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD. // WILL NOT BE SAVED. MODIFY TABLES IN YOUR MODULE SOURCE CODE INSTEAD.
#![allow(unused, clippy::all)] #![allow(unused, clippy::all)]
use super::puzzle_anchor_pack_type::PuzzleAnchorPack;
use super::puzzle_draft_level_type::PuzzleDraftLevel;
use super::puzzle_publication_status_type::PuzzlePublicationStatus;
use super::puzzle_work_profile_type::PuzzleWorkProfile;
use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws}; use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, Copy, PartialEq, Debug)]
#[sats(crate = __lib)]
#[derive(Eq, Hash)]
pub enum PuzzleGalleryAnchorStatus {
Missing,
Inferred,
Confirmed,
Locked,
}
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct PuzzleGalleryAnchorItem {
pub key: String,
pub label: String,
pub value: String,
pub status: PuzzleGalleryAnchorStatus,
}
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct PuzzleGalleryAnchorPack {
pub theme_promise: PuzzleGalleryAnchorItem,
pub visual_subject: PuzzleGalleryAnchorItem,
pub visual_mood: PuzzleGalleryAnchorItem,
pub composition_hooks: PuzzleGalleryAnchorItem,
pub tags_and_forbidden: PuzzleGalleryAnchorItem,
}
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct PuzzleGalleryGeneratedImageCandidate {
pub candidate_id: String,
pub image_src: String,
pub asset_id: String,
pub prompt: String,
pub actual_prompt: Option<String>,
pub source_type: String,
pub selected: bool,
}
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct PuzzleGalleryAudioAsset {
pub task_id: String,
pub provider: String,
pub asset_object_id: Option<String>,
pub asset_kind: Option<String>,
pub audio_src: String,
pub prompt: Option<String>,
pub title: Option<String>,
pub updated_at: Option<String>,
}
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct PuzzleGalleryDraftLevel {
pub level_id: String,
pub level_name: String,
pub picture_description: String,
pub picture_reference: Option<String>,
pub ui_background_prompt: Option<String>,
pub ui_background_image_src: Option<String>,
pub ui_background_image_object_key: Option<String>,
pub background_music: Option<PuzzleGalleryAudioAsset>,
pub candidates: Vec<PuzzleGalleryGeneratedImageCandidate>,
pub selected_candidate_id: Option<String>,
pub cover_image_src: Option<String>,
pub cover_asset_id: Option<String>,
pub generation_status: String,
}
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, Copy, PartialEq, Debug)]
#[sats(crate = __lib)]
#[derive(Eq, Hash)]
pub enum PuzzleGalleryPublicationStatus {
Draft,
Published,
}
#[derive(__lib::ser::Serialize, __lib::de::Deserialize, Clone, PartialEq, Debug)]
#[sats(crate = __lib)]
pub struct PuzzleGalleryViewRow {
pub work_id: String,
pub profile_id: String,
pub owner_user_id: String,
pub source_session_id: Option<String>,
pub author_display_name: String,
pub work_title: String,
pub work_description: String,
pub level_name: String,
pub summary: String,
pub theme_tags: Vec<String>,
pub cover_image_src: Option<String>,
pub cover_asset_id: Option<String>,
pub levels: Vec<PuzzleGalleryDraftLevel>,
pub publication_status: PuzzleGalleryPublicationStatus,
pub updated_at_micros: i64,
pub published_at_micros: Option<i64>,
pub play_count: u32,
pub remix_count: u32,
pub like_count: u32,
pub recent_play_count_7d: u32,
pub point_incentive_total_half_points: u64,
pub point_incentive_claimed_points: u64,
pub publish_ready: bool,
pub anchor_pack: PuzzleGalleryAnchorPack,
}
impl From<PuzzleGalleryAnchorStatus> for module_puzzle::PuzzleAnchorStatus {
fn from(status: PuzzleGalleryAnchorStatus) -> Self {
match status {
PuzzleGalleryAnchorStatus::Missing => Self::Missing,
PuzzleGalleryAnchorStatus::Inferred => Self::Inferred,
PuzzleGalleryAnchorStatus::Confirmed => Self::Confirmed,
PuzzleGalleryAnchorStatus::Locked => Self::Locked,
}
}
}
impl From<PuzzleGalleryAnchorItem> for module_puzzle::PuzzleAnchorItem {
fn from(item: PuzzleGalleryAnchorItem) -> Self {
Self {
key: item.key,
label: item.label,
value: item.value,
status: item.status.into(),
}
}
}
impl From<PuzzleGalleryAnchorPack> for module_puzzle::PuzzleAnchorPack {
fn from(pack: PuzzleGalleryAnchorPack) -> Self {
Self {
theme_promise: pack.theme_promise.into(),
visual_subject: pack.visual_subject.into(),
visual_mood: pack.visual_mood.into(),
composition_hooks: pack.composition_hooks.into(),
tags_and_forbidden: pack.tags_and_forbidden.into(),
}
}
}
impl From<PuzzleGalleryGeneratedImageCandidate>
for module_puzzle::PuzzleGeneratedImageCandidate
{
fn from(candidate: PuzzleGalleryGeneratedImageCandidate) -> Self {
Self {
candidate_id: candidate.candidate_id,
image_src: candidate.image_src,
asset_id: candidate.asset_id,
prompt: candidate.prompt,
actual_prompt: candidate.actual_prompt,
source_type: candidate.source_type,
selected: candidate.selected,
}
}
}
impl From<PuzzleGalleryAudioAsset> for module_puzzle::PuzzleAudioAsset {
fn from(asset: PuzzleGalleryAudioAsset) -> Self {
Self {
task_id: asset.task_id,
provider: asset.provider,
asset_object_id: asset.asset_object_id,
asset_kind: asset.asset_kind,
audio_src: asset.audio_src,
prompt: asset.prompt,
title: asset.title,
updated_at: asset.updated_at,
}
}
}
impl From<PuzzleGalleryDraftLevel> for module_puzzle::PuzzleDraftLevel {
fn from(level: PuzzleGalleryDraftLevel) -> Self {
Self {
level_id: level.level_id,
level_name: level.level_name,
picture_description: level.picture_description,
picture_reference: level.picture_reference,
ui_background_prompt: level.ui_background_prompt,
ui_background_image_src: level.ui_background_image_src,
ui_background_image_object_key: level.ui_background_image_object_key,
background_music: level.background_music.map(Into::into),
candidates: level.candidates.into_iter().map(Into::into).collect(),
selected_candidate_id: level.selected_candidate_id,
cover_image_src: level.cover_image_src,
cover_asset_id: level.cover_asset_id,
generation_status: level.generation_status,
}
}
}
impl From<PuzzleGalleryPublicationStatus> for module_puzzle::PuzzlePublicationStatus {
fn from(status: PuzzleGalleryPublicationStatus) -> Self {
match status {
PuzzleGalleryPublicationStatus::Draft => Self::Draft,
PuzzleGalleryPublicationStatus::Published => Self::Published,
}
}
}
impl From<PuzzleGalleryViewRow> for module_puzzle::PuzzleWorkProfile {
fn from(row: PuzzleGalleryViewRow) -> Self {
Self {
work_id: row.work_id,
profile_id: row.profile_id,
owner_user_id: row.owner_user_id,
source_session_id: row.source_session_id,
author_display_name: row.author_display_name,
work_title: row.work_title,
work_description: row.work_description,
level_name: row.level_name,
summary: row.summary,
theme_tags: row.theme_tags,
cover_image_src: row.cover_image_src,
cover_asset_id: row.cover_asset_id,
levels: row.levels.into_iter().map(Into::into).collect(),
publication_status: row.publication_status.into(),
updated_at_micros: row.updated_at_micros,
published_at_micros: row.published_at_micros,
play_count: row.play_count,
remix_count: row.remix_count,
like_count: row.like_count,
recent_play_count_7d: row.recent_play_count_7d,
point_incentive_total_half_points: row.point_incentive_total_half_points,
point_incentive_claimed_points: row.point_incentive_claimed_points,
publish_ready: row.publish_ready,
anchor_pack: row.anchor_pack.into(),
}
}
}
impl __sdk::InModule for PuzzleGalleryViewRow {
type Module = super::RemoteModule;
}
/// Table handle for the table `puzzle_gallery_view`. /// Table handle for the table `puzzle_gallery_view`.
/// ///
/// Obtain a handle from the [`PuzzleGalleryViewTableAccess::puzzle_gallery_view`] method on [`super::RemoteTables`], /// Obtain a handle from the [`PuzzleGalleryViewTableAccess::puzzle_gallery_view`] method on [`super::RemoteTables`],
@@ -17,7 +251,7 @@ use spacetimedb_sdk::__codegen::{self as __sdk, __lib, __sats, __ws};
/// but to directly chain method calls, /// but to directly chain method calls,
/// like `ctx.db.puzzle_gallery_view().on_insert(...)`. /// like `ctx.db.puzzle_gallery_view().on_insert(...)`.
pub struct PuzzleGalleryViewTableHandle<'ctx> { pub struct PuzzleGalleryViewTableHandle<'ctx> {
imp: __sdk::TableHandle<PuzzleWorkProfile>, imp: __sdk::TableHandle<PuzzleGalleryViewRow>,
ctx: std::marker::PhantomData<&'ctx super::RemoteTables>, ctx: std::marker::PhantomData<&'ctx super::RemoteTables>,
} }
@@ -36,7 +270,7 @@ impl PuzzleGalleryViewTableAccess for super::RemoteTables {
PuzzleGalleryViewTableHandle { PuzzleGalleryViewTableHandle {
imp: self imp: self
.imp .imp
.get_table::<PuzzleWorkProfile>("puzzle_gallery_view"), .get_table::<PuzzleGalleryViewRow>("puzzle_gallery_view"),
ctx: std::marker::PhantomData, ctx: std::marker::PhantomData,
} }
} }
@@ -46,13 +280,13 @@ pub struct PuzzleGalleryViewInsertCallbackId(__sdk::CallbackId);
pub struct PuzzleGalleryViewDeleteCallbackId(__sdk::CallbackId); pub struct PuzzleGalleryViewDeleteCallbackId(__sdk::CallbackId);
impl<'ctx> __sdk::Table for PuzzleGalleryViewTableHandle<'ctx> { impl<'ctx> __sdk::Table for PuzzleGalleryViewTableHandle<'ctx> {
type Row = PuzzleWorkProfile; type Row = PuzzleGalleryViewRow;
type EventContext = super::EventContext; type EventContext = super::EventContext;
fn count(&self) -> u64 { fn count(&self) -> u64 {
self.imp.count() self.imp.count()
} }
fn iter(&self) -> impl Iterator<Item = PuzzleWorkProfile> + '_ { fn iter(&self) -> impl Iterator<Item = PuzzleGalleryViewRow> + '_ {
self.imp.iter() self.imp.iter()
} }
@@ -85,32 +319,32 @@ impl<'ctx> __sdk::Table for PuzzleGalleryViewTableHandle<'ctx> {
#[doc(hidden)] #[doc(hidden)]
pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) { pub(super) fn register_table(client_cache: &mut __sdk::ClientCache<super::RemoteModule>) {
let _table = client_cache.get_or_make_table::<PuzzleWorkProfile>("puzzle_gallery_view"); let _table = client_cache.get_or_make_table::<PuzzleGalleryViewRow>("puzzle_gallery_view");
} }
#[doc(hidden)] #[doc(hidden)]
pub(super) fn parse_table_update( pub(super) fn parse_table_update(
raw_updates: __ws::v2::TableUpdate, raw_updates: __ws::v2::TableUpdate,
) -> __sdk::Result<__sdk::TableUpdate<PuzzleWorkProfile>> { ) -> __sdk::Result<__sdk::TableUpdate<PuzzleGalleryViewRow>> {
__sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| { __sdk::TableUpdate::parse_table_update(raw_updates).map_err(|e| {
__sdk::InternalError::failed_parse("TableUpdate<PuzzleWorkProfile>", "TableUpdate") __sdk::InternalError::failed_parse("TableUpdate<PuzzleGalleryViewRow>", "TableUpdate")
.with_cause(e) .with_cause(e)
.into() .into()
}) })
} }
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
/// Extension trait for query builder access to the table `PuzzleWorkProfile`. /// Extension trait for query builder access to the table `PuzzleGalleryViewRow`.
/// ///
/// Implemented for [`__sdk::QueryTableAccessor`]. /// Implemented for [`__sdk::QueryTableAccessor`].
pub trait puzzle_gallery_viewQueryTableAccess { pub trait puzzle_gallery_viewQueryTableAccess {
#[allow(non_snake_case)] #[allow(non_snake_case)]
/// Get a query builder for the table `PuzzleWorkProfile`. /// Get a query builder for the table `PuzzleGalleryViewRow`.
fn puzzle_gallery_view(&self) -> __sdk::__query_builder::Table<PuzzleWorkProfile>; fn puzzle_gallery_view(&self) -> __sdk::__query_builder::Table<PuzzleGalleryViewRow>;
} }
impl puzzle_gallery_viewQueryTableAccess for __sdk::QueryTableAccessor { impl puzzle_gallery_viewQueryTableAccess for __sdk::QueryTableAccessor {
fn puzzle_gallery_view(&self) -> __sdk::__query_builder::Table<PuzzleWorkProfile> { fn puzzle_gallery_view(&self) -> __sdk::__query_builder::Table<PuzzleGalleryViewRow> {
__sdk::__query_builder::Table::new("puzzle_gallery_view") __sdk::__query_builder::Table::new("puzzle_gallery_view")
} }
} }

View File

@@ -9,19 +9,22 @@ impl SpacetimeClient {
validate_npc_battle_interaction_input(&input)?; validate_npc_battle_interaction_input(&input)?;
let procedure_input = input.into(); let procedure_input = input.into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "resolve_npc_battle_interaction_and_return",
.procedures() move |connection, sender| {
.resolve_npc_battle_interaction_and_return_then( connection
procedure_input, .procedures()
move |_, result| { .resolve_npc_battle_interaction_and_return_then(
let mapped = result procedure_input,
.map_err(SpacetimeClientError::from_sdk_error) move |_, result| {
.and_then(map_npc_battle_interaction_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}, .and_then(map_npc_battle_interaction_procedure_result);
); send_once(&sender, mapped);
}) },
);
},
)
.await .await
} }
} }

View File

@@ -59,7 +59,7 @@ impl SpacetimeClient {
created_at_micros: input.created_at_micros, created_at_micros: input.created_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("create_puzzle_agent_session", move |connection, sender| {
connection.procedures().create_puzzle_agent_session_then( connection.procedures().create_puzzle_agent_session_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -83,7 +83,7 @@ impl SpacetimeClient {
owner_user_id, owner_user_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_puzzle_agent_session", move |connection, sender| {
connection.procedures().get_puzzle_agent_session_then( connection.procedures().get_puzzle_agent_session_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -108,7 +108,7 @@ impl SpacetimeClient {
saved_at_micros: input.saved_at_micros, saved_at_micros: input.saved_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("save_puzzle_form_draft", move |connection, sender| {
connection.procedures().save_puzzle_form_draft_then( connection.procedures().save_puzzle_form_draft_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -134,7 +134,7 @@ impl SpacetimeClient {
submitted_at_micros: input.submitted_at_micros, submitted_at_micros: input.submitted_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("submit_puzzle_agent_message", move |connection, sender| {
connection.procedures().submit_puzzle_agent_message_then( connection.procedures().submit_puzzle_agent_message_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -164,16 +164,19 @@ impl SpacetimeClient {
updated_at_micros: input.updated_at_micros, updated_at_micros: input.updated_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "finalize_puzzle_agent_message_turn",
.procedures() move |connection, sender| {
.finalize_puzzle_agent_message_turn_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .finalize_puzzle_agent_message_turn_then(procedure_input, move |_, result| {
.and_then(map_puzzle_agent_session_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_puzzle_agent_session_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -189,7 +192,7 @@ impl SpacetimeClient {
compiled_at_micros, compiled_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("compile_puzzle_agent_draft", move |connection, sender| {
connection.procedures().compile_puzzle_agent_draft_then( connection.procedures().compile_puzzle_agent_draft_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -216,7 +219,7 @@ impl SpacetimeClient {
saved_at_micros: input.saved_at_micros, saved_at_micros: input.saved_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("save_puzzle_generated_images", move |connection, sender| {
connection.procedures().save_puzzle_generated_images_then( connection.procedures().save_puzzle_generated_images_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -245,7 +248,7 @@ impl SpacetimeClient {
saved_at_micros: input.saved_at_micros, saved_at_micros: input.saved_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("save_puzzle_ui_background", move |connection, sender| {
connection.procedures().save_puzzle_ui_background_then( connection.procedures().save_puzzle_ui_background_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -271,7 +274,7 @@ impl SpacetimeClient {
selected_at_micros: input.selected_at_micros, selected_at_micros: input.selected_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("select_puzzle_cover_image", move |connection, sender| {
connection.procedures().select_puzzle_cover_image_then( connection.procedures().select_puzzle_cover_image_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -304,7 +307,7 @@ impl SpacetimeClient {
published_at_micros: input.published_at_micros, published_at_micros: input.published_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("publish_puzzle_work", move |connection, sender| {
connection connection
.procedures() .procedures()
.publish_puzzle_work_then(procedure_input, move |_, result| { .publish_puzzle_work_then(procedure_input, move |_, result| {
@@ -323,7 +326,7 @@ impl SpacetimeClient {
) -> Result<Vec<PuzzleWorkProfileRecord>, SpacetimeClientError> { ) -> Result<Vec<PuzzleWorkProfileRecord>, SpacetimeClientError> {
let procedure_input = PuzzleWorksListInput { owner_user_id }; let procedure_input = PuzzleWorksListInput { owner_user_id };
self.call_after_connect(move |connection, sender| { self.call_after_connect("list_puzzle_works", move |connection, sender| {
connection connection
.procedures() .procedures()
.list_puzzle_works_then(procedure_input, move |_, result| { .list_puzzle_works_then(procedure_input, move |_, result| {
@@ -342,7 +345,7 @@ impl SpacetimeClient {
) -> Result<PuzzleWorkProfileRecord, SpacetimeClientError> { ) -> Result<PuzzleWorkProfileRecord, SpacetimeClientError> {
let procedure_input = PuzzleWorkGetInput { profile_id }; let procedure_input = PuzzleWorkGetInput { profile_id };
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_puzzle_work_detail", move |connection, sender| {
connection.procedures().get_puzzle_work_detail_then( connection.procedures().get_puzzle_work_detail_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -374,7 +377,7 @@ impl SpacetimeClient {
updated_at_micros: input.updated_at_micros, updated_at_micros: input.updated_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("update_puzzle_work", move |connection, sender| {
connection connection
.procedures() .procedures()
.update_puzzle_work_then(procedure_input, move |_, result| { .update_puzzle_work_then(procedure_input, move |_, result| {
@@ -397,7 +400,7 @@ impl SpacetimeClient {
owner_user_id, owner_user_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("delete_puzzle_work", move |connection, sender| {
connection connection
.procedures() .procedures()
.delete_puzzle_work_then(procedure_input, move |_, result| { .delete_puzzle_work_then(procedure_input, move |_, result| {
@@ -420,16 +423,19 @@ impl SpacetimeClient {
claimed_at_micros: input.claimed_at_micros, claimed_at_micros: input.claimed_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "claim_puzzle_work_point_incentive",
.procedures() move |connection, sender| {
.claim_puzzle_work_point_incentive_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(|error| SpacetimeClientError::Procedure(error.to_string())) .claim_puzzle_work_point_incentive_then(procedure_input, move |_, result| {
.and_then(map_puzzle_work_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
}); .and_then(map_puzzle_work_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -443,7 +449,7 @@ impl SpacetimeClient {
Ok(items Ok(items
.into_iter() .into_iter()
.map(|item| { .map(|item| {
let mut record = map_puzzle_work_profile(item); let mut record = map_puzzle_work_profile(item.into());
record.recent_play_count_7d = recent_play_counts record.recent_play_count_7d = recent_play_counts
.get(&record.profile_id) .get(&record.profile_id)
.copied() .copied()
@@ -461,7 +467,7 @@ impl SpacetimeClient {
) -> Result<PuzzleWorkProfileRecord, SpacetimeClientError> { ) -> Result<PuzzleWorkProfileRecord, SpacetimeClientError> {
let procedure_input = PuzzleWorkGetInput { profile_id }; let procedure_input = PuzzleWorkGetInput { profile_id };
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_puzzle_gallery_detail", move |connection, sender| {
connection.procedures().get_puzzle_gallery_detail_then( connection.procedures().get_puzzle_gallery_detail_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -485,7 +491,7 @@ impl SpacetimeClient {
liked_at_micros: input.liked_at_micros, liked_at_micros: input.liked_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("record_puzzle_work_like", move |connection, sender| {
connection.procedures().record_puzzle_work_like_then( connection.procedures().record_puzzle_work_like_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -514,7 +520,7 @@ impl SpacetimeClient {
remixed_at_micros: input.remixed_at_micros, remixed_at_micros: input.remixed_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("remix_puzzle_work", move |connection, sender| {
connection connection
.procedures() .procedures()
.remix_puzzle_work_then(procedure_input, move |_, result| { .remix_puzzle_work_then(procedure_input, move |_, result| {
@@ -539,7 +545,7 @@ impl SpacetimeClient {
started_at_micros: input.started_at_micros, started_at_micros: input.started_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("start_puzzle_run", move |connection, sender| {
connection connection
.procedures() .procedures()
.start_puzzle_run_then(procedure_input, move |_, result| { .start_puzzle_run_then(procedure_input, move |_, result| {
@@ -562,7 +568,7 @@ impl SpacetimeClient {
owner_user_id, owner_user_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_puzzle_run", move |connection, sender| {
connection connection
.procedures() .procedures()
.get_puzzle_run_then(procedure_input, move |_, result| { .get_puzzle_run_then(procedure_input, move |_, result| {
@@ -587,7 +593,7 @@ impl SpacetimeClient {
swapped_at_micros: input.swapped_at_micros, swapped_at_micros: input.swapped_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("swap_puzzle_pieces", move |connection, sender| {
connection connection
.procedures() .procedures()
.swap_puzzle_pieces_then(procedure_input, move |_, result| { .swap_puzzle_pieces_then(procedure_input, move |_, result| {
@@ -613,7 +619,7 @@ impl SpacetimeClient {
dragged_at_micros: input.dragged_at_micros, dragged_at_micros: input.dragged_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("drag_puzzle_piece_or_group", move |connection, sender| {
connection.procedures().drag_puzzle_piece_or_group_then( connection.procedures().drag_puzzle_piece_or_group_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -638,7 +644,7 @@ impl SpacetimeClient {
advanced_at_micros: input.advanced_at_micros, advanced_at_micros: input.advanced_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("advance_puzzle_next_level", move |connection, sender| {
connection.procedures().advance_puzzle_next_level_then( connection.procedures().advance_puzzle_next_level_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -663,7 +669,7 @@ impl SpacetimeClient {
updated_at_micros: input.updated_at_micros, updated_at_micros: input.updated_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("update_puzzle_run_pause", move |connection, sender| {
connection.procedures().update_puzzle_run_pause_then( connection.procedures().update_puzzle_run_pause_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -689,7 +695,7 @@ impl SpacetimeClient {
spent_points: input.spent_points, spent_points: input.spent_points,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("use_puzzle_runtime_prop", move |connection, sender| {
connection.procedures().use_puzzle_runtime_prop_then( connection.procedures().use_puzzle_runtime_prop_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -717,16 +723,19 @@ impl SpacetimeClient {
submitted_at_micros: input.submitted_at_micros, submitted_at_micros: input.submitted_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "submit_puzzle_leaderboard_entry",
.procedures() move |connection, sender| {
.submit_puzzle_leaderboard_entry_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .submit_puzzle_leaderboard_entry_then(procedure_input, move |_, result| {
.and_then(map_puzzle_run_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_puzzle_run_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
} }

View File

@@ -4,7 +4,7 @@ impl SpacetimeClient {
pub async fn get_creation_entry_config( pub async fn get_creation_entry_config(
&self, &self,
) -> Result<CreationEntryConfigRecord, SpacetimeClientError> { ) -> Result<CreationEntryConfigRecord, SpacetimeClientError> {
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_creation_entry_config", move |connection, sender| {
connection connection
.procedures() .procedures()
.get_creation_entry_config_then(move |_, result| { .get_creation_entry_config_then(move |_, result| {
@@ -22,16 +22,19 @@ impl SpacetimeClient {
input: module_runtime::CreationEntryTypeAdminUpsertInput, input: module_runtime::CreationEntryTypeAdminUpsertInput,
) -> Result<CreationEntryConfigRecord, SpacetimeClientError> { ) -> Result<CreationEntryConfigRecord, SpacetimeClientError> {
let procedure_input: CreationEntryTypeAdminUpsertInput = input.into(); let procedure_input: CreationEntryTypeAdminUpsertInput = input.into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "upsert_creation_entry_type_config",
.procedures() move |connection, sender| {
.upsert_creation_entry_type_config_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .upsert_creation_entry_type_config_then(procedure_input, move |_, result| {
.and_then(map_creation_entry_config_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_creation_entry_config_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -43,17 +46,20 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection.procedures().get_runtime_setting_or_default_then( "get_runtime_setting_or_default",
procedure_input, move |connection, sender| {
move |_, result| { connection.procedures().get_runtime_setting_or_default_then(
let mapped = result procedure_input,
.map_err(SpacetimeClientError::from_sdk_error) move |_, result| {
.and_then(map_runtime_setting_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}, .and_then(map_runtime_setting_procedure_result);
); send_once(&sender, mapped);
}) },
);
},
)
.await .await
} }
@@ -65,7 +71,7 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect("list_platform_browse_history", move |connection, sender| {
connection.procedures().list_platform_browse_history_then( connection.procedures().list_platform_browse_history_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -87,7 +93,7 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_profile_dashboard", move |connection, sender| {
connection.procedures().get_profile_dashboard_then( connection.procedures().get_profile_dashboard_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -109,7 +115,7 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect("list_profile_wallet_ledger", move |connection, sender| {
connection.procedures().list_profile_wallet_ledger_then( connection.procedures().list_profile_wallet_ledger_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -131,19 +137,22 @@ impl SpacetimeClient {
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))? .map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "grant_new_user_registration_wallet_reward",
.procedures() move |connection, sender| {
.grant_new_user_registration_wallet_reward_then( connection
procedure_input, .procedures()
move |_, result| { .grant_new_user_registration_wallet_reward_then(
let mapped = result procedure_input,
.map_err(|error| SpacetimeClientError::Procedure(error.to_string())) move |_, result| {
.and_then(map_runtime_profile_wallet_adjustment_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
}, .and_then(map_runtime_profile_wallet_adjustment_procedure_result);
); send_once(&sender, mapped);
}) },
);
},
)
.await .await
} }
@@ -163,19 +172,22 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "consume_profile_wallet_points_and_return",
.procedures() move |connection, sender| {
.consume_profile_wallet_points_and_return_then( connection
procedure_input, .procedures()
move |_, result| { .consume_profile_wallet_points_and_return_then(
let mapped = result procedure_input,
.map_err(SpacetimeClientError::from_sdk_error) move |_, result| {
.and_then(map_runtime_profile_wallet_adjustment_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}, .and_then(map_runtime_profile_wallet_adjustment_procedure_result);
); send_once(&sender, mapped);
}) },
);
},
)
.await .await
} }
@@ -195,16 +207,22 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "refund_profile_wallet_points_and_return",
.procedures() move |connection, sender| {
.refund_profile_wallet_points_and_return_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .refund_profile_wallet_points_and_return_then(
.and_then(map_runtime_profile_wallet_adjustment_procedure_result); procedure_input,
send_once(&sender, mapped); move |_, result| {
}); let mapped = result
}) .map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_runtime_profile_wallet_adjustment_procedure_result);
send_once(&sender, mapped);
},
);
},
)
.await .await
} }
@@ -216,7 +234,7 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_profile_recharge_center", move |connection, sender| {
connection.procedures().get_profile_recharge_center_then( connection.procedures().get_profile_recharge_center_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -252,19 +270,22 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "create_profile_recharge_order_and_return",
.procedures() move |connection, sender| {
.create_profile_recharge_order_and_return_then( connection
procedure_input, .procedures()
move |_, result| { .create_profile_recharge_order_and_return_then(
let mapped = result procedure_input,
.map_err(SpacetimeClientError::from_sdk_error) move |_, result| {
.and_then(map_runtime_profile_recharge_order_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}, .and_then(map_runtime_profile_recharge_order_procedure_result);
); send_once(&sender, mapped);
}) },
);
},
)
.await .await
} }
@@ -282,16 +303,22 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "get_profile_recharge_order_and_return",
.procedures() move |connection, sender| {
.get_profile_recharge_order_and_return_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .get_profile_recharge_order_and_return_then(
.and_then(map_runtime_profile_recharge_order_procedure_result); procedure_input,
send_once(&sender, mapped); move |_, result| {
}); let mapped = result
}) .map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_runtime_profile_recharge_order_procedure_result);
send_once(&sender, mapped);
},
);
},
)
.await .await
} }
@@ -315,19 +342,22 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "mark_profile_recharge_order_paid_and_return",
.procedures() move |connection, sender| {
.mark_profile_recharge_order_paid_and_return_then( connection
procedure_input, .procedures()
move |_, result| { .mark_profile_recharge_order_paid_and_return_then(
let mapped = result procedure_input,
.map_err(SpacetimeClientError::from_sdk_error) move |_, result| {
.and_then(map_runtime_profile_recharge_order_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}, .and_then(map_runtime_profile_recharge_order_procedure_result);
); send_once(&sender, mapped);
}) },
);
},
)
.await .await
} }
@@ -349,16 +379,19 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "submit_profile_feedback_and_return",
.procedures() move |connection, sender| {
.submit_profile_feedback_and_return_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .submit_profile_feedback_and_return_then(procedure_input, move |_, result| {
.and_then(map_runtime_profile_feedback_submission_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_runtime_profile_feedback_submission_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -370,16 +403,19 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "get_profile_referral_invite_center",
.procedures() move |connection, sender| {
.get_profile_referral_invite_center_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .get_profile_referral_invite_center_then(procedure_input, move |_, result| {
.and_then(map_runtime_referral_invite_center_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_runtime_referral_invite_center_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -394,16 +430,19 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "redeem_profile_referral_invite_code",
.procedures() move |connection, sender| {
.redeem_profile_referral_invite_code_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .redeem_profile_referral_invite_code_then(procedure_input, move |_, result| {
.and_then(map_runtime_referral_redeem_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_runtime_referral_redeem_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -418,7 +457,7 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect("redeem_profile_reward_code", move |connection, sender| {
connection.procedures().redeem_profile_reward_code_then( connection.procedures().redeem_profile_reward_code_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -481,16 +520,19 @@ impl SpacetimeClient {
occurred_at_micros, occurred_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "record_tracking_event_and_return",
.procedures() move |connection, sender| {
.record_tracking_event_and_return_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .record_tracking_event_and_return_then(procedure_input, move |_, result| {
.and_then(map_runtime_tracking_event_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_runtime_tracking_event_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -502,7 +544,7 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_profile_task_center", move |connection, sender| {
connection.procedures().get_profile_task_center_then( connection.procedures().get_profile_task_center_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -525,16 +567,22 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "claim_profile_task_reward_and_return",
.procedures() move |connection, sender| {
.claim_profile_task_reward_and_return_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .claim_profile_task_reward_and_return_then(
.and_then(map_runtime_profile_task_claim_procedure_result); procedure_input,
send_once(&sender, mapped); move |_, result| {
}); let mapped = result
}) .map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_runtime_profile_task_claim_procedure_result);
send_once(&sender, mapped);
},
);
},
)
.await .await
} }
@@ -550,7 +598,7 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect("query_analytics_metric", move |connection, sender| {
connection.procedures().query_analytics_metric_then( connection.procedures().query_analytics_metric_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -572,16 +620,19 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "admin_list_profile_task_configs",
.procedures() move |connection, sender| {
.admin_list_profile_task_configs_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .admin_list_profile_task_configs_then(procedure_input, move |_, result| {
.and_then(map_runtime_profile_task_config_admin_list_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_runtime_profile_task_config_admin_list_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -617,16 +668,19 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "admin_upsert_profile_task_config",
.procedures() move |connection, sender| {
.admin_upsert_profile_task_config_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .admin_upsert_profile_task_config_then(procedure_input, move |_, result| {
.and_then(map_runtime_profile_task_config_admin_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_runtime_profile_task_config_admin_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -644,16 +698,19 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "admin_disable_profile_task_config",
.procedures() move |connection, sender| {
.admin_disable_profile_task_config_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .admin_disable_profile_task_config_then(procedure_input, move |_, result| {
.and_then(map_runtime_profile_task_config_admin_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_runtime_profile_task_config_admin_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -666,16 +723,24 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "admin_list_profile_recharge_products",
.procedures() move |connection, sender| {
.admin_list_profile_recharge_products_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .admin_list_profile_recharge_products_then(
.and_then(map_runtime_profile_recharge_product_admin_list_procedure_result); procedure_input,
send_once(&sender, mapped); move |_, result| {
}); let mapped = result
}) .map_err(SpacetimeClientError::from_sdk_error)
.and_then(
map_runtime_profile_recharge_product_admin_list_procedure_result,
);
send_once(&sender, mapped);
},
);
},
)
.await .await
} }
@@ -716,16 +781,24 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "admin_upsert_profile_recharge_product",
.procedures() move |connection, sender| {
.admin_upsert_profile_recharge_product_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .admin_upsert_profile_recharge_product_then(
.and_then(map_runtime_profile_recharge_product_admin_procedure_result); procedure_input,
send_once(&sender, mapped); move |_, result| {
}); let mapped = result
}) .map_err(SpacetimeClientError::from_sdk_error)
.and_then(
map_runtime_profile_recharge_product_admin_procedure_result,
);
send_once(&sender, mapped);
},
);
},
)
.await .await
} }
@@ -755,16 +828,19 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "admin_upsert_profile_redeem_code",
.procedures() move |connection, sender| {
.admin_upsert_profile_redeem_code_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .admin_upsert_profile_redeem_code_then(procedure_input, move |_, result| {
.and_then(map_runtime_profile_redeem_code_admin_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_runtime_profile_redeem_code_admin_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -776,16 +852,19 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "admin_list_profile_redeem_codes",
.procedures() move |connection, sender| {
.admin_list_profile_redeem_codes_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .admin_list_profile_redeem_codes_then(procedure_input, move |_, result| {
.and_then(map_runtime_profile_redeem_code_admin_list_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_runtime_profile_redeem_code_admin_list_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -803,16 +882,19 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "admin_disable_profile_redeem_code",
.procedures() move |connection, sender| {
.admin_disable_profile_redeem_code_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .admin_disable_profile_redeem_code_then(procedure_input, move |_, result| {
.and_then(map_runtime_profile_redeem_code_admin_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_runtime_profile_redeem_code_admin_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -836,16 +918,19 @@ impl SpacetimeClient {
.map_err(|error| SpacetimeClientError::Runtime(error.to_string()))? .map_err(|error| SpacetimeClientError::Runtime(error.to_string()))?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "admin_upsert_profile_invite_code",
.procedures() move |connection, sender| {
.admin_upsert_profile_invite_code_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(|error| SpacetimeClientError::Procedure(error.to_string())) .admin_upsert_profile_invite_code_then(procedure_input, move |_, result| {
.and_then(map_runtime_profile_invite_code_admin_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
}); .and_then(map_runtime_profile_invite_code_admin_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -857,16 +942,19 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "admin_list_profile_invite_codes",
.procedures() move |connection, sender| {
.admin_list_profile_invite_codes_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .admin_list_profile_invite_codes_then(procedure_input, move |_, result| {
.and_then(map_runtime_profile_invite_code_admin_list_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_runtime_profile_invite_code_admin_list_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -878,7 +966,7 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_profile_play_stats", move |connection, sender| {
connection.procedures().get_profile_play_stats_then( connection.procedures().get_profile_play_stats_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -900,7 +988,7 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_runtime_snapshot", move |connection, sender| {
connection connection
.procedures() .procedures()
.get_runtime_snapshot_then(procedure_input, move |_, result| { .get_runtime_snapshot_then(procedure_input, move |_, result| {
@@ -933,16 +1021,19 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "upsert_runtime_snapshot_and_return",
.procedures() move |connection, sender| {
.upsert_runtime_snapshot_and_return_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .upsert_runtime_snapshot_and_return_then(procedure_input, move |_, result| {
.and_then(map_runtime_snapshot_required_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_runtime_snapshot_required_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -954,16 +1045,19 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "delete_runtime_snapshot_and_return",
.procedures() move |connection, sender| {
.delete_runtime_snapshot_and_return_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .delete_runtime_snapshot_and_return_then(procedure_input, move |_, result| {
.and_then(map_runtime_snapshot_delete_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_runtime_snapshot_delete_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -975,7 +1069,7 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect("list_profile_save_archives", move |connection, sender| {
connection.procedures().list_profile_save_archives_then( connection.procedures().list_profile_save_archives_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -999,16 +1093,22 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "resume_profile_save_archive_and_return",
.procedures() move |connection, sender| {
.resume_profile_save_archive_and_return_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .resume_profile_save_archive_and_return_then(
.and_then(map_runtime_profile_save_archive_resume_procedure_result); procedure_input,
send_once(&sender, mapped); move |_, result| {
}); let mapped = result
}) .map_err(SpacetimeClientError::from_sdk_error)
.and_then(map_runtime_profile_save_archive_resume_procedure_result);
send_once(&sender, mapped);
},
);
},
)
.await .await
} }
@@ -1028,16 +1128,19 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "upsert_runtime_setting_and_return",
.procedures() move |connection, sender| {
.upsert_runtime_setting_and_return_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(SpacetimeClientError::from_sdk_error) .upsert_runtime_setting_and_return_then(procedure_input, move |_, result| {
.and_then(map_runtime_setting_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}); .and_then(map_runtime_setting_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -1052,19 +1155,22 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "upsert_platform_browse_history_and_return",
.procedures() move |connection, sender| {
.upsert_platform_browse_history_and_return_then( connection
procedure_input, .procedures()
move |_, result| { .upsert_platform_browse_history_and_return_then(
let mapped = result procedure_input,
.map_err(SpacetimeClientError::from_sdk_error) move |_, result| {
.and_then(map_runtime_browse_history_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}, .and_then(map_runtime_browse_history_procedure_result);
); send_once(&sender, mapped);
}) },
);
},
)
.await .await
} }
@@ -1076,19 +1182,22 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "clear_platform_browse_history_and_return",
.procedures() move |connection, sender| {
.clear_platform_browse_history_and_return_then( connection
procedure_input, .procedures()
move |_, result| { .clear_platform_browse_history_and_return_then(
let mapped = result procedure_input,
.map_err(SpacetimeClientError::from_sdk_error) move |_, result| {
.and_then(map_runtime_browse_history_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}, .and_then(map_runtime_browse_history_procedure_result);
); send_once(&sender, mapped);
}) },
);
},
)
.await .await
} }
} }

View File

@@ -16,16 +16,19 @@ impl SpacetimeClient {
created_at_micros: input.created_at_micros, created_at_micros: input.created_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "create_square_hole_agent_session",
.procedures() move |connection, sender| {
.create_square_hole_agent_session_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(|error| SpacetimeClientError::Procedure(error.to_string())) .create_square_hole_agent_session_then(procedure_input, move |_, result| {
.and_then(map_square_hole_agent_session_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
}); .and_then(map_square_hole_agent_session_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -39,17 +42,20 @@ impl SpacetimeClient {
owner_user_id, owner_user_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection.procedures().get_square_hole_agent_session_then( "get_square_hole_agent_session",
procedure_input, move |connection, sender| {
move |_, result| { connection.procedures().get_square_hole_agent_session_then(
let mapped = result procedure_input,
.map_err(|error| SpacetimeClientError::Procedure(error.to_string())) move |_, result| {
.and_then(map_square_hole_agent_session_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
}, .and_then(map_square_hole_agent_session_procedure_result);
); send_once(&sender, mapped);
}) },
);
},
)
.await .await
} }
@@ -65,16 +71,19 @@ impl SpacetimeClient {
submitted_at_micros: input.submitted_at_micros, submitted_at_micros: input.submitted_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "submit_square_hole_agent_message",
.procedures() move |connection, sender| {
.submit_square_hole_agent_message_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(|error| SpacetimeClientError::Procedure(error.to_string())) .submit_square_hole_agent_message_then(procedure_input, move |_, result| {
.and_then(map_square_hole_agent_session_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
}); .and_then(map_square_hole_agent_session_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -94,16 +103,22 @@ impl SpacetimeClient {
error_message: input.error_message, error_message: input.error_message,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "finalize_square_hole_agent_message_turn",
.procedures() move |connection, sender| {
.finalize_square_hole_agent_message_turn_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(|error| SpacetimeClientError::Procedure(error.to_string())) .finalize_square_hole_agent_message_turn_then(
.and_then(map_square_hole_agent_session_procedure_result); procedure_input,
send_once(&sender, mapped); move |_, result| {
}); let mapped = result
}) .map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
.and_then(map_square_hole_agent_session_procedure_result);
send_once(&sender, mapped);
},
);
},
)
.await .await
} }
@@ -123,7 +138,7 @@ impl SpacetimeClient {
compiled_at_micros: input.compiled_at_micros, compiled_at_micros: input.compiled_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("compile_square_hole_draft", move |connection, sender| {
connection.procedures().compile_square_hole_draft_then( connection.procedures().compile_square_hole_draft_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -159,7 +174,7 @@ impl SpacetimeClient {
updated_at_micros: input.updated_at_micros, updated_at_micros: input.updated_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("update_square_hole_work", move |connection, sender| {
connection.procedures().update_square_hole_work_then( connection.procedures().update_square_hole_work_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -185,7 +200,7 @@ impl SpacetimeClient {
published_at_micros, published_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("publish_square_hole_work", move |connection, sender| {
connection.procedures().publish_square_hole_work_then( connection.procedures().publish_square_hole_work_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -225,7 +240,7 @@ impl SpacetimeClient {
&self, &self,
procedure_input: SquareHoleWorksListInput, procedure_input: SquareHoleWorksListInput,
) -> Result<Vec<SquareHoleWorkProfileRecord>, SpacetimeClientError> { ) -> Result<Vec<SquareHoleWorkProfileRecord>, SpacetimeClientError> {
self.call_after_connect(move |connection, sender| { self.call_after_connect("list_square_hole_works", move |connection, sender| {
connection.procedures().list_square_hole_works_then( connection.procedures().list_square_hole_works_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -249,7 +264,7 @@ impl SpacetimeClient {
owner_user_id, owner_user_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_square_hole_work_detail", move |connection, sender| {
connection.procedures().get_square_hole_work_detail_then( connection.procedures().get_square_hole_work_detail_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -273,7 +288,7 @@ impl SpacetimeClient {
owner_user_id, owner_user_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("delete_square_hole_work", move |connection, sender| {
connection.procedures().delete_square_hole_work_then( connection.procedures().delete_square_hole_work_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -298,7 +313,7 @@ impl SpacetimeClient {
started_at_ms: input.started_at_ms, started_at_ms: input.started_at_ms,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("start_square_hole_run", move |connection, sender| {
connection.procedures().start_square_hole_run_then( connection.procedures().start_square_hole_run_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -322,7 +337,7 @@ impl SpacetimeClient {
owner_user_id, owner_user_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_square_hole_run", move |connection, sender| {
connection connection
.procedures() .procedures()
.get_square_hole_run_then(procedure_input, move |_, result| { .get_square_hole_run_then(procedure_input, move |_, result| {
@@ -349,7 +364,7 @@ impl SpacetimeClient {
dropped_at_ms: input.dropped_at_ms, dropped_at_ms: input.dropped_at_ms,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("drop_square_hole_shape", move |connection, sender| {
connection.procedures().drop_square_hole_shape_then( connection.procedures().drop_square_hole_shape_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -379,7 +394,7 @@ impl SpacetimeClient {
stopped_at_ms: input.stopped_at_ms, stopped_at_ms: input.stopped_at_ms,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("stop_square_hole_run", move |connection, sender| {
connection connection
.procedures() .procedures()
.stop_square_hole_run_then(procedure_input, move |_, result| { .stop_square_hole_run_then(procedure_input, move |_, result| {
@@ -403,7 +418,7 @@ impl SpacetimeClient {
restarted_at_ms: input.restarted_at_ms, restarted_at_ms: input.restarted_at_ms,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("restart_square_hole_run", move |connection, sender| {
connection.procedures().restart_square_hole_run_then( connection.procedures().restart_square_hole_run_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -427,7 +442,7 @@ impl SpacetimeClient {
finished_at_ms: input.finished_at_ms, finished_at_ms: input.finished_at_ms,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("finish_square_hole_time_up", move |connection, sender| {
connection.procedures().finish_square_hole_time_up_then( connection.procedures().finish_square_hole_time_up_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {

View File

@@ -23,17 +23,20 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection.procedures().begin_story_session_and_return_then( "begin_story_session_and_return",
procedure_input, move |connection, sender| {
move |_, result| { connection.procedures().begin_story_session_and_return_then(
let mapped = result procedure_input,
.map_err(SpacetimeClientError::from_sdk_error) move |_, result| {
.and_then(map_story_session_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(SpacetimeClientError::from_sdk_error)
}, .and_then(map_story_session_procedure_result);
); send_once(&sender, mapped);
}) },
);
},
)
.await .await
} }
@@ -55,7 +58,7 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect("continue_story_and_return", move |connection, sender| {
connection.procedures().continue_story_and_return_then( connection.procedures().continue_story_and_return_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -77,7 +80,7 @@ impl SpacetimeClient {
.map_err(SpacetimeClientError::validation_failed)? .map_err(SpacetimeClientError::validation_failed)?
.into(); .into();
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_story_session_state", move |connection, sender| {
connection.procedures().get_story_session_state_then( connection.procedures().get_story_session_state_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {

View File

@@ -0,0 +1,75 @@
use std::time::Duration;
use opentelemetry::{KeyValue, global, metrics::Counter};
use crate::SpacetimeClientError;
// SpacetimeDB procedure 指标只使用 procedure / status_class 等低基数字段,避免把用户或作品 ID 写进指标标签。
pub(crate) struct ProcedureMetricsGuard {
procedure: &'static str,
started_at: std::time::Instant,
}
pub(crate) fn begin_procedure(procedure: &'static str) -> ProcedureMetricsGuard {
ProcedureMetricsGuard {
procedure,
started_at: std::time::Instant::now(),
}
}
impl ProcedureMetricsGuard {
pub(crate) fn finish<T>(&self, result: &Result<T, SpacetimeClientError>) {
let duration = self.started_at.elapsed();
record_procedure(self.procedure, duration, result.is_err());
}
}
struct SpacetimeMetrics {
calls: Counter<u64>,
errors: Counter<u64>,
duration_ms: opentelemetry::metrics::Histogram<f64>,
}
fn spacetime_metrics() -> &'static SpacetimeMetrics {
static METRICS: std::sync::OnceLock<SpacetimeMetrics> = std::sync::OnceLock::new();
METRICS.get_or_init(|| {
let meter = global::meter("genarrative-spacetime-client");
SpacetimeMetrics {
calls: meter
.u64_counter("genarrative.spacetime.procedure.calls")
.with_description("SpacetimeDB procedure call count")
.build(),
errors: meter
.u64_counter("genarrative.spacetime.procedure.errors")
.with_description("SpacetimeDB procedure error count")
.build(),
duration_ms: meter
.f64_histogram("genarrative.spacetime.procedure.duration_ms")
.with_unit("ms")
.with_description("SpacetimeDB procedure duration in milliseconds")
.build(),
}
})
}
fn record_procedure(
procedure: &'static str,
duration: Duration,
failed: bool,
) {
let labels = vec![
KeyValue::new("procedure", procedure),
KeyValue::new(
"status_class",
if failed { "error" } else { "ok" },
),
];
let metrics = spacetime_metrics();
metrics.calls.add(1, &labels);
metrics
.duration_ms
.record(duration.as_secs_f64() * 1000.0, &labels);
if failed {
metrics.errors.add(1, &labels);
}
}

View File

@@ -28,16 +28,19 @@ impl SpacetimeClient {
created_at_micros: input.created_at_micros, created_at_micros: input.created_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "create_visual_novel_agent_session",
.procedures() move |connection, sender| {
.create_visual_novel_agent_session_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(|error| SpacetimeClientError::Procedure(error.to_string())) .create_visual_novel_agent_session_then(procedure_input, move |_, result| {
.and_then(map_visual_novel_agent_session_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
}); .and_then(map_visual_novel_agent_session_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -51,17 +54,20 @@ impl SpacetimeClient {
owner_user_id, owner_user_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection.procedures().get_visual_novel_agent_session_then( "get_visual_novel_agent_session",
procedure_input, move |connection, sender| {
move |_, result| { connection.procedures().get_visual_novel_agent_session_then(
let mapped = result procedure_input,
.map_err(|error| SpacetimeClientError::Procedure(error.to_string())) move |_, result| {
.and_then(map_visual_novel_agent_session_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
}, .and_then(map_visual_novel_agent_session_procedure_result);
); send_once(&sender, mapped);
}) },
);
},
)
.await .await
} }
@@ -77,16 +83,19 @@ impl SpacetimeClient {
submitted_at_micros: input.submitted_at_micros, submitted_at_micros: input.submitted_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "submit_visual_novel_agent_message",
.procedures() move |connection, sender| {
.submit_visual_novel_agent_message_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(|error| SpacetimeClientError::Procedure(error.to_string())) .submit_visual_novel_agent_message_then(procedure_input, move |_, result| {
.and_then(map_visual_novel_agent_session_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
}); .and_then(map_visual_novel_agent_session_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -107,19 +116,22 @@ impl SpacetimeClient {
error_message: input.error_message, error_message: input.error_message,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "finalize_visual_novel_agent_message_turn",
.procedures() move |connection, sender| {
.finalize_visual_novel_agent_message_turn_then( connection
procedure_input, .procedures()
move |_, result| { .finalize_visual_novel_agent_message_turn_then(
let mapped = result procedure_input,
.map_err(|error| SpacetimeClientError::Procedure(error.to_string())) move |_, result| {
.and_then(map_visual_novel_agent_session_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
}, .and_then(map_visual_novel_agent_session_procedure_result);
); send_once(&sender, mapped);
}) },
);
},
)
.await .await
} }
@@ -140,16 +152,19 @@ impl SpacetimeClient {
compiled_at_micros: input.compiled_at_micros, compiled_at_micros: input.compiled_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "compile_visual_novel_work_profile",
.procedures() move |connection, sender| {
.compile_visual_novel_work_profile_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(|error| SpacetimeClientError::Procedure(error.to_string())) .compile_visual_novel_work_profile_then(procedure_input, move |_, result| {
.and_then(map_visual_novel_agent_session_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
}); .and_then(map_visual_novel_agent_session_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -170,7 +185,7 @@ impl SpacetimeClient {
updated_at_micros: input.updated_at_micros, updated_at_micros: input.updated_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("update_visual_novel_work", move |connection, sender| {
connection.procedures().update_visual_novel_work_then( connection.procedures().update_visual_novel_work_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -196,7 +211,7 @@ impl SpacetimeClient {
published_at_micros, published_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("publish_visual_novel_work", move |connection, sender| {
connection.procedures().publish_visual_novel_work_then( connection.procedures().publish_visual_novel_work_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -236,7 +251,7 @@ impl SpacetimeClient {
&self, &self,
procedure_input: VisualNovelWorksListInput, procedure_input: VisualNovelWorksListInput,
) -> Result<Vec<VisualNovelWorkProfileRecord>, SpacetimeClientError> { ) -> Result<Vec<VisualNovelWorkProfileRecord>, SpacetimeClientError> {
self.call_after_connect(move |connection, sender| { self.call_after_connect("list_visual_novel_works", move |connection, sender| {
connection.procedures().list_visual_novel_works_then( connection.procedures().list_visual_novel_works_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -260,7 +275,7 @@ impl SpacetimeClient {
owner_user_id, owner_user_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_visual_novel_work_detail", move |connection, sender| {
connection.procedures().get_visual_novel_work_detail_then( connection.procedures().get_visual_novel_work_detail_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -284,7 +299,7 @@ impl SpacetimeClient {
owner_user_id, owner_user_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("delete_visual_novel_work", move |connection, sender| {
connection.procedures().delete_visual_novel_work_then( connection.procedures().delete_visual_novel_work_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -311,7 +326,7 @@ impl SpacetimeClient {
started_at_micros: input.started_at_micros, started_at_micros: input.started_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("start_visual_novel_run", move |connection, sender| {
connection.procedures().start_visual_novel_run_then( connection.procedures().start_visual_novel_run_then(
procedure_input, procedure_input,
move |_, result| { move |_, result| {
@@ -335,7 +350,7 @@ impl SpacetimeClient {
owner_user_id, owner_user_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect("get_visual_novel_run", move |connection, sender| {
connection connection
.procedures() .procedures()
.get_visual_novel_run_then(procedure_input, move |_, result| { .get_visual_novel_run_then(procedure_input, move |_, result| {
@@ -367,16 +382,19 @@ impl SpacetimeClient {
updated_at_micros: input.updated_at_micros, updated_at_micros: input.updated_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "upsert_visual_novel_run_snapshot",
.procedures() move |connection, sender| {
.upsert_visual_novel_run_snapshot_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(|error| SpacetimeClientError::Procedure(error.to_string())) .upsert_visual_novel_run_snapshot_then(procedure_input, move |_, result| {
.and_then(map_visual_novel_run_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
}); .and_then(map_visual_novel_run_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -397,19 +415,22 @@ impl SpacetimeClient {
created_at_micros: input.created_at_micros, created_at_micros: input.created_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "append_visual_novel_runtime_history_entry",
.procedures() move |connection, sender| {
.append_visual_novel_runtime_history_entry_then( connection
procedure_input, .procedures()
move |_, result| { .append_visual_novel_runtime_history_entry_then(
let mapped = result procedure_input,
.map_err(|error| SpacetimeClientError::Procedure(error.to_string())) move |_, result| {
.and_then(map_visual_novel_history_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
}, .and_then(map_visual_novel_history_procedure_result);
); send_once(&sender, mapped);
}) },
);
},
)
.await .await
} }
@@ -423,16 +444,19 @@ impl SpacetimeClient {
owner_user_id, owner_user_id,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "list_visual_novel_runtime_history",
.procedures() move |connection, sender| {
.list_visual_novel_runtime_history_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(|error| SpacetimeClientError::Procedure(error.to_string())) .list_visual_novel_runtime_history_then(procedure_input, move |_, result| {
.and_then(map_visual_novel_history_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
}); .and_then(map_visual_novel_history_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
@@ -452,16 +476,19 @@ impl SpacetimeClient {
occurred_at_micros: input.occurred_at_micros, occurred_at_micros: input.occurred_at_micros,
}; };
self.call_after_connect(move |connection, sender| { self.call_after_connect(
connection "record_visual_novel_runtime_event",
.procedures() move |connection, sender| {
.record_visual_novel_runtime_event_then(procedure_input, move |_, result| { connection
let mapped = result .procedures()
.map_err(|error| SpacetimeClientError::Procedure(error.to_string())) .record_visual_novel_runtime_event_then(procedure_input, move |_, result| {
.and_then(map_visual_novel_runtime_event_procedure_result); let mapped = result
send_once(&sender, mapped); .map_err(|error| SpacetimeClientError::Procedure(error.to_string()))
}); .and_then(map_visual_novel_runtime_event_procedure_result);
}) send_once(&sender, mapped);
});
},
)
.await .await
} }
} }

View File

@@ -216,12 +216,12 @@ pub fn create_puzzle_agent_session(
match ctx.try_with_tx(|tx| create_puzzle_agent_session_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| create_puzzle_agent_session_tx(tx, input.clone())) {
Ok(session) => PuzzleAgentSessionProcedureResult { Ok(session) => PuzzleAgentSessionProcedureResult {
ok: true, ok: true,
session: Some(session), session_json: Some(serialize_json(&session)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleAgentSessionProcedureResult { Err(message) => PuzzleAgentSessionProcedureResult {
ok: false, ok: false,
session: None, session_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -235,12 +235,12 @@ pub fn get_puzzle_agent_session(
match ctx.try_with_tx(|tx| get_puzzle_agent_session_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| get_puzzle_agent_session_tx(tx, input.clone())) {
Ok(session) => PuzzleAgentSessionProcedureResult { Ok(session) => PuzzleAgentSessionProcedureResult {
ok: true, ok: true,
session: Some(session), session_json: Some(serialize_json(&session)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleAgentSessionProcedureResult { Err(message) => PuzzleAgentSessionProcedureResult {
ok: false, ok: false,
session: None, session_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -254,12 +254,12 @@ pub fn submit_puzzle_agent_message(
match ctx.try_with_tx(|tx| submit_puzzle_agent_message_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| submit_puzzle_agent_message_tx(tx, input.clone())) {
Ok(session) => PuzzleAgentSessionProcedureResult { Ok(session) => PuzzleAgentSessionProcedureResult {
ok: true, ok: true,
session: Some(session), session_json: Some(serialize_json(&session)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleAgentSessionProcedureResult { Err(message) => PuzzleAgentSessionProcedureResult {
ok: false, ok: false,
session: None, session_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -273,12 +273,12 @@ pub fn finalize_puzzle_agent_message_turn(
match ctx.try_with_tx(|tx| finalize_puzzle_agent_message_turn_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| finalize_puzzle_agent_message_turn_tx(tx, input.clone())) {
Ok(session) => PuzzleAgentSessionProcedureResult { Ok(session) => PuzzleAgentSessionProcedureResult {
ok: true, ok: true,
session: Some(session), session_json: Some(serialize_json(&session)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleAgentSessionProcedureResult { Err(message) => PuzzleAgentSessionProcedureResult {
ok: false, ok: false,
session: None, session_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -292,12 +292,12 @@ pub fn compile_puzzle_agent_draft(
match ctx.try_with_tx(|tx| compile_puzzle_agent_draft_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| compile_puzzle_agent_draft_tx(tx, input.clone())) {
Ok(session) => PuzzleAgentSessionProcedureResult { Ok(session) => PuzzleAgentSessionProcedureResult {
ok: true, ok: true,
session: Some(session), session_json: Some(serialize_json(&session)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleAgentSessionProcedureResult { Err(message) => PuzzleAgentSessionProcedureResult {
ok: false, ok: false,
session: None, session_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -313,12 +313,12 @@ pub fn save_puzzle_form_draft(
match ctx.try_with_tx(|tx| save_puzzle_form_draft_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| save_puzzle_form_draft_tx(tx, input.clone())) {
Ok(session) => PuzzleAgentSessionProcedureResult { Ok(session) => PuzzleAgentSessionProcedureResult {
ok: true, ok: true,
session: Some(session), session_json: Some(serialize_json(&session)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleAgentSessionProcedureResult { Err(message) => PuzzleAgentSessionProcedureResult {
ok: false, ok: false,
session: None, session_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -332,12 +332,12 @@ pub fn save_puzzle_generated_images(
match ctx.try_with_tx(|tx| save_puzzle_generated_images_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| save_puzzle_generated_images_tx(tx, input.clone())) {
Ok(session) => PuzzleAgentSessionProcedureResult { Ok(session) => PuzzleAgentSessionProcedureResult {
ok: true, ok: true,
session: Some(session), session_json: Some(serialize_json(&session)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleAgentSessionProcedureResult { Err(message) => PuzzleAgentSessionProcedureResult {
ok: false, ok: false,
session: None, session_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -351,12 +351,12 @@ pub fn save_puzzle_ui_background(
match ctx.try_with_tx(|tx| save_puzzle_ui_background_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| save_puzzle_ui_background_tx(tx, input.clone())) {
Ok(session) => PuzzleAgentSessionProcedureResult { Ok(session) => PuzzleAgentSessionProcedureResult {
ok: true, ok: true,
session: Some(session), session_json: Some(serialize_json(&session)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleAgentSessionProcedureResult { Err(message) => PuzzleAgentSessionProcedureResult {
ok: false, ok: false,
session: None, session_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -370,12 +370,12 @@ pub fn select_puzzle_cover_image(
match ctx.try_with_tx(|tx| select_puzzle_cover_image_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| select_puzzle_cover_image_tx(tx, input.clone())) {
Ok(session) => PuzzleAgentSessionProcedureResult { Ok(session) => PuzzleAgentSessionProcedureResult {
ok: true, ok: true,
session: Some(session), session_json: Some(serialize_json(&session)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleAgentSessionProcedureResult { Err(message) => PuzzleAgentSessionProcedureResult {
ok: false, ok: false,
session: None, session_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -389,12 +389,12 @@ pub fn publish_puzzle_work(
match ctx.try_with_tx(|tx| publish_puzzle_work_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| publish_puzzle_work_tx(tx, input.clone())) {
Ok(item) => PuzzleWorkProcedureResult { Ok(item) => PuzzleWorkProcedureResult {
ok: true, ok: true,
item: Some(item), item_json: Some(serialize_json(&item)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleWorkProcedureResult { Err(message) => PuzzleWorkProcedureResult {
ok: false, ok: false,
item: None, item_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -408,12 +408,12 @@ pub fn list_puzzle_works(
match ctx.try_with_tx(|tx| list_puzzle_works_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| list_puzzle_works_tx(tx, input.clone())) {
Ok(items) => PuzzleWorksProcedureResult { Ok(items) => PuzzleWorksProcedureResult {
ok: true, ok: true,
items, items_json: Some(serialize_json(&items)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleWorksProcedureResult { Err(message) => PuzzleWorksProcedureResult {
ok: false, ok: false,
items: Vec::new(), items_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -427,12 +427,12 @@ pub fn get_puzzle_work_detail(
match ctx.try_with_tx(|tx| get_puzzle_work_detail_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| get_puzzle_work_detail_tx(tx, input.clone())) {
Ok(item) => PuzzleWorkProcedureResult { Ok(item) => PuzzleWorkProcedureResult {
ok: true, ok: true,
item: Some(item), item_json: Some(serialize_json(&item)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleWorkProcedureResult { Err(message) => PuzzleWorkProcedureResult {
ok: false, ok: false,
item: None, item_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -446,12 +446,12 @@ pub fn update_puzzle_work(
match ctx.try_with_tx(|tx| update_puzzle_work_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| update_puzzle_work_tx(tx, input.clone())) {
Ok(item) => PuzzleWorkProcedureResult { Ok(item) => PuzzleWorkProcedureResult {
ok: true, ok: true,
item: Some(item), item_json: Some(serialize_json(&item)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleWorkProcedureResult { Err(message) => PuzzleWorkProcedureResult {
ok: false, ok: false,
item: None, item_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -465,12 +465,12 @@ pub fn delete_puzzle_work(
match ctx.try_with_tx(|tx| delete_puzzle_work_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| delete_puzzle_work_tx(tx, input.clone())) {
Ok(items) => PuzzleWorksProcedureResult { Ok(items) => PuzzleWorksProcedureResult {
ok: true, ok: true,
items, items_json: Some(serialize_json(&items)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleWorksProcedureResult { Err(message) => PuzzleWorksProcedureResult {
ok: false, ok: false,
items: Vec::new(), items_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -481,12 +481,12 @@ pub fn list_puzzle_gallery(ctx: &mut ProcedureContext) -> PuzzleWorksProcedureRe
match ctx.try_with_tx(|tx| list_puzzle_gallery_tx(tx)) { match ctx.try_with_tx(|tx| list_puzzle_gallery_tx(tx)) {
Ok(items) => PuzzleWorksProcedureResult { Ok(items) => PuzzleWorksProcedureResult {
ok: true, ok: true,
items, items_json: Some(serialize_json(&items)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleWorksProcedureResult { Err(message) => PuzzleWorksProcedureResult {
ok: false, ok: false,
items: Vec::new(), items_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -500,12 +500,12 @@ pub fn get_puzzle_gallery_detail(
match ctx.try_with_tx(|tx| get_puzzle_gallery_detail_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| get_puzzle_gallery_detail_tx(tx, input.clone())) {
Ok(item) => PuzzleWorkProcedureResult { Ok(item) => PuzzleWorkProcedureResult {
ok: true, ok: true,
item: Some(item), item_json: Some(serialize_json(&item)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleWorkProcedureResult { Err(message) => PuzzleWorkProcedureResult {
ok: false, ok: false,
item: None, item_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -519,12 +519,12 @@ pub fn record_puzzle_work_like(
match ctx.try_with_tx(|tx| record_puzzle_work_like_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| record_puzzle_work_like_tx(tx, input.clone())) {
Ok(item) => PuzzleWorkProcedureResult { Ok(item) => PuzzleWorkProcedureResult {
ok: true, ok: true,
item: Some(item), item_json: Some(serialize_json(&item)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleWorkProcedureResult { Err(message) => PuzzleWorkProcedureResult {
ok: false, ok: false,
item: None, item_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -538,12 +538,12 @@ pub fn remix_puzzle_work(
match ctx.try_with_tx(|tx| remix_puzzle_work_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| remix_puzzle_work_tx(tx, input.clone())) {
Ok(session) => PuzzleAgentSessionProcedureResult { Ok(session) => PuzzleAgentSessionProcedureResult {
ok: true, ok: true,
session: Some(session), session_json: Some(serialize_json(&session)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleAgentSessionProcedureResult { Err(message) => PuzzleAgentSessionProcedureResult {
ok: false, ok: false,
session: None, session_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -557,12 +557,12 @@ pub fn start_puzzle_run(
match ctx.try_with_tx(|tx| start_puzzle_run_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| start_puzzle_run_tx(tx, input.clone())) {
Ok(run) => PuzzleRunProcedureResult { Ok(run) => PuzzleRunProcedureResult {
ok: true, ok: true,
run: Some(run), run_json: Some(serialize_json(&run)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleRunProcedureResult { Err(message) => PuzzleRunProcedureResult {
ok: false, ok: false,
run: None, run_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -576,12 +576,12 @@ pub fn get_puzzle_run(
match ctx.try_with_tx(|tx| get_puzzle_run_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| get_puzzle_run_tx(tx, input.clone())) {
Ok(run) => PuzzleRunProcedureResult { Ok(run) => PuzzleRunProcedureResult {
ok: true, ok: true,
run: Some(run), run_json: Some(serialize_json(&run)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleRunProcedureResult { Err(message) => PuzzleRunProcedureResult {
ok: false, ok: false,
run: None, run_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -595,12 +595,12 @@ pub fn swap_puzzle_pieces(
match ctx.try_with_tx(|tx| swap_puzzle_pieces_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| swap_puzzle_pieces_tx(tx, input.clone())) {
Ok(run) => PuzzleRunProcedureResult { Ok(run) => PuzzleRunProcedureResult {
ok: true, ok: true,
run: Some(run), run_json: Some(serialize_json(&run)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleRunProcedureResult { Err(message) => PuzzleRunProcedureResult {
ok: false, ok: false,
run: None, run_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -614,12 +614,12 @@ pub fn drag_puzzle_piece_or_group(
match ctx.try_with_tx(|tx| drag_puzzle_piece_or_group_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| drag_puzzle_piece_or_group_tx(tx, input.clone())) {
Ok(run) => PuzzleRunProcedureResult { Ok(run) => PuzzleRunProcedureResult {
ok: true, ok: true,
run: Some(run), run_json: Some(serialize_json(&run)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleRunProcedureResult { Err(message) => PuzzleRunProcedureResult {
ok: false, ok: false,
run: None, run_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -633,12 +633,12 @@ pub fn advance_puzzle_next_level(
match ctx.try_with_tx(|tx| advance_puzzle_next_level_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| advance_puzzle_next_level_tx(tx, input.clone())) {
Ok(run) => PuzzleRunProcedureResult { Ok(run) => PuzzleRunProcedureResult {
ok: true, ok: true,
run: Some(run), run_json: Some(serialize_json(&run)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleRunProcedureResult { Err(message) => PuzzleRunProcedureResult {
ok: false, ok: false,
run: None, run_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -652,12 +652,12 @@ pub fn update_puzzle_run_pause(
match ctx.try_with_tx(|tx| update_puzzle_run_pause_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| update_puzzle_run_pause_tx(tx, input.clone())) {
Ok(run) => PuzzleRunProcedureResult { Ok(run) => PuzzleRunProcedureResult {
ok: true, ok: true,
run: Some(run), run_json: Some(serialize_json(&run)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleRunProcedureResult { Err(message) => PuzzleRunProcedureResult {
ok: false, ok: false,
run: None, run_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -671,12 +671,12 @@ pub fn use_puzzle_runtime_prop(
match ctx.try_with_tx(|tx| use_puzzle_runtime_prop_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| use_puzzle_runtime_prop_tx(tx, input.clone())) {
Ok(run) => PuzzleRunProcedureResult { Ok(run) => PuzzleRunProcedureResult {
ok: true, ok: true,
run: Some(run), run_json: Some(serialize_json(&run)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleRunProcedureResult { Err(message) => PuzzleRunProcedureResult {
ok: false, ok: false,
run: None, run_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -690,12 +690,12 @@ pub fn claim_puzzle_work_point_incentive(
match ctx.try_with_tx(|tx| claim_puzzle_work_point_incentive_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| claim_puzzle_work_point_incentive_tx(tx, input.clone())) {
Ok(item) => PuzzleWorkProcedureResult { Ok(item) => PuzzleWorkProcedureResult {
ok: true, ok: true,
item: Some(item), item_json: Some(serialize_json(&item)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleWorkProcedureResult { Err(message) => PuzzleWorkProcedureResult {
ok: false, ok: false,
item: None, item_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }
@@ -709,12 +709,12 @@ pub fn submit_puzzle_leaderboard_entry(
match ctx.try_with_tx(|tx| submit_puzzle_leaderboard_entry_tx(tx, input.clone())) { match ctx.try_with_tx(|tx| submit_puzzle_leaderboard_entry_tx(tx, input.clone())) {
Ok(run) => PuzzleRunProcedureResult { Ok(run) => PuzzleRunProcedureResult {
ok: true, ok: true,
run: Some(run), run_json: Some(serialize_json(&run)),
error_message: None, error_message: None,
}, },
Err(message) => PuzzleRunProcedureResult { Err(message) => PuzzleRunProcedureResult {
ok: false, ok: false,
run: None, run_json: None,
error_message: Some(message), error_message: Some(message),
}, },
} }

View File

@@ -58,7 +58,7 @@ export default defineConfig(({mode}) => {
entries: ['index.html'], entries: ['index.html'],
}, },
build: { build: {
chunkSizeWarningLimit: 800, chunkSizeWarningLimit: 1000,
}, },
server: { server: {
// HMR is disabled in AI Studio via DISABLE_HMR env var. // HMR is disabled in AI Studio via DISABLE_HMR env var.