@bardway/trpg-pixi 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/NOTICE +10 -0
- package/NOTICE.md +1 -0
- package/README.md +25 -2
- package/dist/AnimationMilestones.d.ts +17 -0
- package/dist/BattleActionMotionMath.d.ts +24 -0
- package/dist/BattleActionPresentationRecipes.d.ts +11 -0
- package/dist/BattleFxLibrary.d.ts +16 -0
- package/dist/BattlePresentationEngine.d.ts +26 -0
- package/dist/BattlePresentationPoseRegistry.d.ts +25 -0
- package/dist/BattlePresentationRecipe.d.ts +48 -0
- package/dist/BattleSequenceScheduler.d.ts +11 -0
- package/dist/DisplayEventQueue.d.ts +24 -0
- package/dist/PixiAnimationActivity.d.ts +7 -0
- package/dist/PixiAnimationDirector.d.ts +21 -0
- package/dist/PixiApplicationFactory.d.ts +17 -0
- package/dist/PixiAssetManager.d.ts +70 -0
- package/dist/PixiBattleActionRecipes.d.ts +75 -0
- package/dist/PixiBattleCinematicSurface.d.ts +23 -0
- package/dist/PixiBattleEntryTransition.d.ts +87 -0
- package/dist/PixiBattleFieldSurface.d.ts +125 -0
- package/dist/PixiBattleFxResources.d.ts +154 -0
- package/dist/PixiBattleGrid.d.ts +13 -0
- package/dist/PixiBattleHudPorts.d.ts +192 -0
- package/dist/PixiBattleHudSurface.d.ts +159 -0
- package/dist/PixiBattleLightningResources.d.ts +57 -0
- package/dist/PixiBattleMapDissolve.d.ts +38 -0
- package/dist/PixiBattleSceneTransition.d.ts +30 -0
- package/dist/PixiBattleTokenLifecycleCoordinator.d.ts +44 -0
- package/dist/PixiBattleVisualLayout.d.ts +284 -0
- package/dist/PixiBattleWhipGeometry.d.ts +18 -0
- package/dist/PixiBattleWhipMotion.d.ts +63 -0
- package/dist/PixiBattleWhipResources.d.ts +53 -0
- package/dist/PixiCameraFocusController.d.ts +40 -0
- package/dist/PixiCombatMotion.d.ts +223 -0
- package/dist/PixiCurrentActorCardGlow.d.ts +37 -0
- package/dist/PixiCurrentActorHalo.d.ts +55 -0
- package/dist/PixiDirectionalMotionBlur.d.ts +12 -0
- package/dist/PixiDisplayRenderer.d.ts +85 -0
- package/dist/PixiEffectPlugin.d.ts +25 -0
- package/dist/PixiEndingSurface.d.ts +104 -0
- package/dist/PixiInvestigatorDossierInsanityFilter.d.ts +14 -0
- package/dist/PixiLocalGlowMesh.d.ts +38 -0
- package/dist/PixiMapEdgeShadow.d.ts +36 -0
- package/dist/PixiMapMediaSurface.d.ts +71 -0
- package/dist/PixiMapWorldUtils.d.ts +24 -0
- package/dist/PixiMediaBreathRuntime.d.ts +69 -0
- package/dist/PixiMotion.d.ts +42 -0
- package/dist/PixiObjectiveBreathingGlow.d.ts +39 -0
- package/dist/PixiPartyHudSurface.d.ts +58 -0
- package/dist/PixiPersistentEffectTransition.d.ts +23 -0
- package/dist/PixiPortraitResourceCard.d.ts +147 -0
- package/dist/PixiPreludeStoryTransition.d.ts +35 -0
- package/dist/PixiPreludeSurface.d.ts +203 -0
- package/dist/PixiProgressCinematic.d.ts +65 -0
- package/dist/PixiResultEffectSurface.d.ts +101 -0
- package/dist/PixiRetainedMeterAnimator.d.ts +44 -0
- package/dist/PixiRuntimeContext.d.ts +21 -0
- package/dist/PixiSceneGraph.d.ts +42 -0
- package/dist/PixiSceneMotion.d.ts +41 -0
- package/dist/PixiSceneMotionPorts.d.ts +83 -0
- package/dist/PixiScenePresentationDirector.d.ts +118 -0
- package/dist/PixiSessionLayout.d.ts +61 -0
- package/dist/PixiSessionSkin.d.ts +30 -0
- package/dist/PixiShaderRuntime.d.ts +191 -0
- package/dist/PixiStageFontLoader.d.ts +2 -0
- package/dist/PixiStageMetrics.d.ts +25 -0
- package/dist/PixiStageTheme.d.ts +26 -0
- package/dist/PixiStoryArchiveMotion.d.ts +19 -0
- package/dist/PixiStoryCardCut.d.ts +58 -0
- package/dist/PixiStorySurface.d.ts +285 -0
- package/dist/PixiStoryWorkspaceSurface.d.ts +64 -0
- package/dist/PixiSummaryBoardSurface.d.ts +112 -0
- package/dist/PixiSystemHudSurface.d.ts +73 -0
- package/dist/PixiTeamCheckCinematic.d.ts +34 -0
- package/dist/PixiTextTransitionEffect.d.ts +54 -0
- package/dist/PixiTokenPersistentStatus.d.ts +101 -0
- package/dist/PixiTokenWorld.d.ts +170 -0
- package/dist/PixiTypography.d.ts +96 -0
- package/dist/PixiVideoRuntime.d.ts +61 -0
- package/dist/PixiViewportController.d.ts +25 -0
- package/dist/ResultEffectTuning.d.ts +57 -0
- package/dist/RetainedStageSurface.d.ts +50 -0
- package/dist/SessionFieldEffectRuntime.d.ts +45 -0
- package/dist/SessionSceneHistory.d.ts +10 -0
- package/dist/SessionSceneRegistry.d.ts +31 -0
- package/dist/StoryEventCoordinator.d.ts +61 -0
- package/dist/effects/PixiEffectLayerRegistry.d.ts +54 -0
- package/dist/effects/PixiEffectScope.d.ts +20 -0
- package/dist/effects/PixiStableRandom.d.ts +2 -0
- package/dist/index.d.ts +92 -0
- package/dist/index.js +24184 -0
- package/dist/index.js.map +7 -0
- package/dist/recipes/EffectPrimitiveRuntimeRegistry.d.ts +28 -0
- package/dist/recipes/EffectRecipeExecutor.d.ts +73 -0
- package/dist/recipes/primitives.d.ts +39 -0
- package/dist/recipes/registry.d.ts +57 -0
- package/dist/recipes/schema.d.ts +93 -0
- package/dist/recipes.d.ts +5 -0
- package/dist/recipes.js +1384 -0
- package/dist/recipes.js.map +7 -0
- package/dist/story/PixiStoryPresentationEngine.d.ts +90 -0
- package/dist/story/StoryContentSurface.d.ts +34 -0
- package/dist/story/StoryImageFilter.d.ts +15 -0
- package/dist/story/StoryTimelineClock.d.ts +22 -0
- package/dist/story/StoryVisualMath.d.ts +6 -0
- package/dist/tuning/SessionTuningResolver.d.ts +1 -0
- package/dist/tuning/SessionTuningTypes.d.ts +1 -0
- package/dist/ui/PixiStagePrimitives.d.ts +36 -0
- package/dist/uniforms.d.ts +1 -0
- package/package.json +44 -4
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/recipes/schema.ts", "../src/recipes/primitives.ts", "../src/recipes/registry.ts", "../src/recipes/EffectPrimitiveRuntimeRegistry.ts", "../src/recipes/EffectRecipeExecutor.ts"],
|
|
4
|
+
"sourcesContent": ["const isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\nexport const EFFECT_RECIPE_SCHEMA_VERSION = 4;\nexport const EFFECT_RECIPE_SCOPES = ['story', 'battle'] as const;\nexport const EFFECT_RECIPE_CATEGORIES = ['entrance', 'utility'] as const;\n\nexport const EFFECT_RECIPE_ID_MAX_LENGTH = 80;\nexport const EFFECT_RECIPE_TRACK_ID_MAX_LENGTH = 80;\nexport const EFFECT_RECIPE_PRIMITIVE_ID_MAX_LENGTH = 80;\nexport const EFFECT_RECIPE_NAME_MAX_CODE_POINTS = 80;\nexport const EFFECT_RECIPE_DESCRIPTION_MAX_CODE_POINTS = 240;\nexport const EFFECT_RECIPE_APP_LABEL_MAX_CODE_POINTS = 48;\nexport const EFFECT_RECIPE_APP_SHORT_DESCRIPTION_MAX_CODE_POINTS = 120;\nexport const EFFECT_RECIPE_APP_ICON_ID_MAX_LENGTH = 80;\nexport const EFFECT_RECIPE_MAX_DURATION_MS = 20_000;\nexport const EFFECT_RECIPE_MAX_TRACKS = 24;\nexport const EFFECT_RECIPE_VALUE_MAX_STRING_CODE_POINTS = 240;\nexport const EFFECT_RECIPE_VALUE_MAX_ARRAY_LENGTH = 8;\nexport const EFFECT_RECIPE_TUNING_PATH_MAX_LENGTH = 160;\nexport const EFFECT_RECIPE_APP_ORDER_MAX = 9_999;\n\nexport const EFFECT_RECIPE_STABLE_ID_REGEX = /^[A-Za-z0-9][A-Za-z0-9._:/-]*$/;\nexport const EFFECT_RECIPE_TUNING_PATH_REGEX = /^[A-Za-z][A-Za-z0-9]*(\\.[A-Za-z0-9_-]+)+$/;\n\nconst hasOwn = (value: Record<string, unknown>, key: string): boolean =>\n Object.prototype.hasOwnProperty.call(value, key);\n\nconst codePointLength = (value: string): number => Array.from(value).length;\n\nconst normalizeText = (\n value: unknown,\n maxCodePoints: number,\n allowEmpty = false,\n): string | null => {\n if (typeof value !== 'string') {\n return null;\n }\n\n const normalized = value.trim();\n if ((!allowEmpty && !normalized) || codePointLength(normalized) > maxCodePoints) {\n return null;\n }\n\n return normalized;\n};\n\nconst normalizeNonNegativeInteger = (value: unknown, maxValue: number): number | null => {\n if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 0 || value > maxValue) {\n return null;\n }\n\n return value;\n};\n\nconst createError = (\n code: EffectRecipeValidationErrorCode,\n path: string,\n message: string,\n): EffectRecipeValidationError => ({ code, path, message });\n\nexport type EffectRecipeScope = (typeof EFFECT_RECIPE_SCOPES)[number];\nexport type EffectRecipeCategory = (typeof EFFECT_RECIPE_CATEGORIES)[number];\nexport type EffectRecipeId = string;\nexport type EffectRecipeTrackId = string;\nexport type EffectPrimitiveId = string;\n\nexport interface EffectRecipeTuningPathReference {\n tuningPath: string;\n}\n\nexport type RecipeValue = string | number | boolean | number[] | EffectRecipeTuningPathReference;\nexport type ResolvedRecipeValue = string | number | boolean | number[];\n\nexport interface EffectRecipeAppMetadata {\n label: string;\n shortDescription: string;\n iconId: string;\n order: number;\n}\n\nexport const EFFECT_TARGETS = ['main-content', 'story-workspace', 'full-stage'] as const;\nexport type EffectTarget = (typeof EFFECT_TARGETS)[number];\nexport interface EffectRecipeTrackDefinition {\n target?: EffectTarget;\n id: EffectRecipeTrackId;\n atMs: number;\n durationMs: number;\n primitiveId: EffectPrimitiveId;\n params: Record<string, RecipeValue>;\n enabled: boolean;\n}\n\nexport interface EffectRecipeDefinition {\n schemaVersion: typeof EFFECT_RECIPE_SCHEMA_VERSION;\n id: EffectRecipeId;\n name: string;\n description: string;\n scope: EffectRecipeScope;\n category: EffectRecipeCategory;\n durationMs: number;\n commitAtMs: number;\n app: EffectRecipeAppMetadata;\n tracks: readonly EffectRecipeTrackDefinition[];\n}\n\nexport type EffectRecipeManifestDocument = Readonly<Record<string, unknown>>;\n\nexport type EffectRecipeValidationErrorCode =\n | 'duplicate_recipe_id'\n | 'duplicate_track_id'\n | 'invalid_enum'\n | 'invalid_id'\n | 'invalid_length'\n | 'invalid_param_type'\n | 'invalid_param_value'\n | 'invalid_recipe_value'\n | 'invalid_schema_version'\n | 'invalid_tuning_path'\n | 'invalid_type'\n | 'missing_param'\n | 'out_of_range'\n | 'too_many_items'\n | 'unknown_param'\n | 'unknown_primitive'\n | 'unknown_schema_version'\n | 'unsupported_scope';\n\nexport interface EffectRecipeValidationError {\n code: EffectRecipeValidationErrorCode;\n path: string;\n message: string;\n}\n\nexport interface EffectRecipeMigration {\n schemaVersion: number;\n migrate(definition: EffectRecipeManifestDocument): unknown;\n}\n\nexport interface EffectRecipeMigrationResult {\n document: EffectRecipeManifestDocument | null;\n errors: readonly EffectRecipeValidationError[];\n}\n\nexport interface EffectRecipeDefinitionValidationResult {\n definition: EffectRecipeDefinition | null;\n errors: readonly EffectRecipeValidationError[];\n}\n\nconst v4Migration: EffectRecipeMigration = {\n schemaVersion: 4,\n migrate: (definition) => definition,\n};\n\nexport const EFFECT_RECIPE_MIGRATIONS = [v4Migration] as const;\n\nconst effectRecipeMigrationMap = new Map<number, EffectRecipeMigration>(\n EFFECT_RECIPE_MIGRATIONS.map((migration) => [migration.schemaVersion, migration]),\n);\n\nexport const effectRecipeMigrationRegistry = Object.freeze({\n all: (): readonly EffectRecipeMigration[] => EFFECT_RECIPE_MIGRATIONS,\n get: (schemaVersion: number): EffectRecipeMigration | null =>\n effectRecipeMigrationMap.get(schemaVersion) ?? null,\n});\n\nexport const isEffectRecipeScope = (value: unknown): value is EffectRecipeScope =>\n value === 'story' || value === 'battle';\n\nexport const isEffectRecipeCategory = (value: unknown): value is EffectRecipeCategory =>\n value === 'entrance' || value === 'utility';\n\nexport const isEffectRecipeId = (value: unknown): value is EffectRecipeId => {\n const normalized = normalizeText(value, EFFECT_RECIPE_ID_MAX_LENGTH);\n return normalized !== null && EFFECT_RECIPE_STABLE_ID_REGEX.test(normalized);\n};\n\nexport const isEffectRecipeTrackId = (value: unknown): value is EffectRecipeTrackId => {\n const normalized = normalizeText(value, EFFECT_RECIPE_TRACK_ID_MAX_LENGTH);\n return normalized !== null && EFFECT_RECIPE_STABLE_ID_REGEX.test(normalized);\n};\n\nexport const isEffectPrimitiveId = (value: unknown): value is EffectPrimitiveId => {\n const normalized = normalizeText(value, EFFECT_RECIPE_PRIMITIVE_ID_MAX_LENGTH);\n return normalized !== null && EFFECT_RECIPE_STABLE_ID_REGEX.test(normalized);\n};\n\nexport const isEffectRecipeTuningPath = (value: unknown): value is string => {\n const normalized = normalizeText(value, EFFECT_RECIPE_TUNING_PATH_MAX_LENGTH);\n return normalized !== null && EFFECT_RECIPE_TUNING_PATH_REGEX.test(normalized);\n};\n\nexport const isEffectRecipeTuningPathReference = (\n value: unknown,\n): value is EffectRecipeTuningPathReference =>\n isRecord(value) &&\n Object.keys(value).length === 1 &&\n hasOwn(value, 'tuningPath') &&\n isEffectRecipeTuningPath(value.tuningPath);\n\nexport const isResolvedRecipeValue = (value: unknown): value is ResolvedRecipeValue => {\n if (typeof value === 'string' || typeof value === 'boolean') {\n return true;\n }\n if (typeof value === 'number') {\n return Number.isFinite(value);\n }\n return (\n Array.isArray(value) &&\n value.length <= EFFECT_RECIPE_VALUE_MAX_ARRAY_LENGTH &&\n value.every((entry) => typeof entry === 'number' && Number.isFinite(entry))\n );\n};\n\nconst parseRecipeValue = (\n value: unknown,\n path: string,\n errors: EffectRecipeValidationError[],\n): RecipeValue | null => {\n if (typeof value === 'string') {\n const normalized = normalizeText(value, EFFECT_RECIPE_VALUE_MAX_STRING_CODE_POINTS);\n if (normalized === null) {\n errors.push(\n createError('invalid_length', path, '\u5B57\u7B26\u4E32\u53C2\u6570\u4E0D\u80FD\u4E3A\u7A7A\uFF0C\u4E14\u957F\u5EA6\u5FC5\u987B\u5728\u5141\u8BB8\u8303\u56F4\u5185\u3002'),\n );\n return null;\n }\n return normalized;\n }\n\n if (typeof value === 'number') {\n if (!Number.isFinite(value)) {\n errors.push(createError('invalid_recipe_value', path, '\u6570\u503C\u53C2\u6570\u5FC5\u987B\u662F\u6709\u9650\u6570\u5B57\u3002'));\n return null;\n }\n return value;\n }\n\n if (typeof value === 'boolean') {\n return value;\n }\n\n if (Array.isArray(value)) {\n if (value.length > EFFECT_RECIPE_VALUE_MAX_ARRAY_LENGTH) {\n errors.push(\n createError(\n 'too_many_items',\n path,\n `\u6570\u5B57\u6570\u7EC4\u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC7 ${EFFECT_RECIPE_VALUE_MAX_ARRAY_LENGTH}\u3002`,\n ),\n );\n return null;\n }\n if (!value.every((entry) => typeof entry === 'number' && Number.isFinite(entry))) {\n errors.push(createError('invalid_recipe_value', path, '\u6570\u5B57\u6570\u7EC4\u53EA\u80FD\u5305\u542B\u6709\u9650\u6570\u5B57\u3002'));\n return null;\n }\n return [...value];\n }\n\n if (isRecord(value)) {\n if (!hasOwn(value, 'tuningPath') || Object.keys(value).length !== 1) {\n errors.push(\n createError('invalid_recipe_value', path, '\u5BF9\u8C61\u53C2\u6570\u53EA\u5141\u8BB8\u4F7F\u7528 tuningPath \u5F15\u7528\u3002'),\n );\n return null;\n }\n if (!isEffectRecipeTuningPath(value.tuningPath)) {\n errors.push(\n createError('invalid_tuning_path', `${path}.tuningPath`, 'tuningPath \u683C\u5F0F\u65E0\u6548\u3002'),\n );\n return null;\n }\n return { tuningPath: value.tuningPath.trim() };\n }\n\n errors.push(\n createError(\n 'invalid_recipe_value',\n path,\n '\u53C2\u6570\u503C\u53EA\u5141\u8BB8 string\u3001number\u3001boolean\u3001number[] \u6216 { tuningPath }\u3002',\n ),\n );\n return null;\n};\n\nexport const migrateEffectRecipeDefinition = (value: unknown): EffectRecipeMigrationResult => {\n if (!isRecord(value)) {\n return {\n document: null,\n errors: [createError('invalid_type', '', 'Recipe \u5B9A\u4E49\u5FC5\u987B\u662F\u5BF9\u8C61\u3002')],\n };\n }\n\n const schemaVersion = value.schemaVersion;\n if (typeof schemaVersion !== 'number' || !Number.isSafeInteger(schemaVersion)) {\n return {\n document: null,\n errors: [\n createError('invalid_schema_version', 'schemaVersion', 'schemaVersion \u5FC5\u987B\u662F\u5B89\u5168\u6574\u6570\u3002'),\n ],\n };\n }\n\n const migration = effectRecipeMigrationMap.get(schemaVersion);\n if (!migration) {\n return {\n document: null,\n errors: [\n createError(\n 'unknown_schema_version',\n 'schemaVersion',\n `\u672A\u6CE8\u518C\u7684 recipe schemaVersion: ${schemaVersion}\u3002`,\n ),\n ],\n };\n }\n\n if (value.category === 'sequence' || value.category === 'horror')\n return {\n document: null,\n errors: [createError('invalid_enum', 'category', '\u8BE5\u7C7B Story \u6F14\u51FA\u5DF2\u9000\u5F79\u3002')],\n };\n const migrated = migration.migrate(value);\n if (!isRecord(migrated)) {\n return {\n document: null,\n errors: [createError('invalid_type', '', '\u8FC1\u79FB\u540E\u7684 Recipe \u5B9A\u4E49\u5FC5\u987B\u662F\u5BF9\u8C61\u3002')],\n };\n }\n\n return { document: migrated, errors: [] };\n};\n\nexport const validateEffectRecipeDefinition = (\n value: unknown,\n): EffectRecipeDefinitionValidationResult => {\n const migrationResult = migrateEffectRecipeDefinition(value);\n if (!migrationResult.document) {\n return { definition: null, errors: migrationResult.errors };\n }\n\n const document = migrationResult.document;\n const errors: EffectRecipeValidationError[] = [];\n const schemaVersion = document.schemaVersion;\n if (schemaVersion !== EFFECT_RECIPE_SCHEMA_VERSION) {\n errors.push(\n createError(\n 'invalid_schema_version',\n 'schemaVersion',\n `schemaVersion \u5FC5\u987B\u4E3A ${EFFECT_RECIPE_SCHEMA_VERSION}\u3002`,\n ),\n );\n }\n\n const id = normalizeText(document.id, EFFECT_RECIPE_ID_MAX_LENGTH);\n if (!id || !EFFECT_RECIPE_STABLE_ID_REGEX.test(id)) {\n errors.push(createError('invalid_id', 'id', 'Recipe id \u5FC5\u987B\u662F\u7A33\u5B9A\u6807\u8BC6\u7B26\u3002'));\n }\n\n const name = normalizeText(document.name, EFFECT_RECIPE_NAME_MAX_CODE_POINTS);\n if (!name) {\n errors.push(\n createError('invalid_length', 'name', 'Recipe name \u4E0D\u80FD\u4E3A\u7A7A\uFF0C\u4E14\u957F\u5EA6\u5FC5\u987B\u5728\u5141\u8BB8\u8303\u56F4\u5185\u3002'),\n );\n }\n\n const description = normalizeText(\n document.description,\n EFFECT_RECIPE_DESCRIPTION_MAX_CODE_POINTS,\n );\n if (!description) {\n errors.push(\n createError(\n 'invalid_length',\n 'description',\n 'Recipe description \u4E0D\u80FD\u4E3A\u7A7A\uFF0C\u4E14\u957F\u5EA6\u5FC5\u987B\u5728\u5141\u8BB8\u8303\u56F4\u5185\u3002',\n ),\n );\n }\n\n const scope = document.scope;\n if (!isEffectRecipeScope(scope)) {\n errors.push(createError('invalid_enum', 'scope', 'scope \u5FC5\u987B\u662F story \u6216 battle\u3002'));\n }\n\n const category = document.category;\n if (!isEffectRecipeCategory(category)) {\n errors.push(createError('invalid_enum', 'category', 'category \u5FC5\u987B\u662F entrance \u6216 utility\u3002'));\n }\n\n const durationMs = normalizeNonNegativeInteger(\n document.durationMs,\n EFFECT_RECIPE_MAX_DURATION_MS,\n );\n if (durationMs === null) {\n errors.push(\n createError(\n 'out_of_range',\n 'durationMs',\n `durationMs \u5FC5\u987B\u662F 0 \u5230 ${EFFECT_RECIPE_MAX_DURATION_MS} \u7684\u5B89\u5168\u6574\u6570\u3002`,\n ),\n );\n }\n\n const commitAtMs = normalizeNonNegativeInteger(\n document.commitAtMs,\n EFFECT_RECIPE_MAX_DURATION_MS,\n );\n if (commitAtMs === null) {\n errors.push(\n createError(\n 'out_of_range',\n 'commitAtMs',\n `commitAtMs \u5FC5\u987B\u662F 0 \u5230 ${EFFECT_RECIPE_MAX_DURATION_MS} \u7684\u5B89\u5168\u6574\u6570\u3002`,\n ),\n );\n } else if (durationMs !== null && commitAtMs > durationMs) {\n errors.push(createError('out_of_range', 'commitAtMs', 'commitAtMs \u4E0D\u80FD\u5927\u4E8E durationMs\u3002'));\n }\n\n let app: EffectRecipeAppMetadata | null = null;\n if (!isRecord(document.app)) {\n errors.push(createError('invalid_type', 'app', 'app \u5143\u6570\u636E\u5FC5\u987B\u662F\u5BF9\u8C61\u3002'));\n } else {\n const label = normalizeText(document.app.label, EFFECT_RECIPE_APP_LABEL_MAX_CODE_POINTS);\n if (!label) {\n errors.push(\n createError('invalid_length', 'app.label', 'app.label \u4E0D\u80FD\u4E3A\u7A7A\uFF0C\u4E14\u957F\u5EA6\u5FC5\u987B\u5728\u5141\u8BB8\u8303\u56F4\u5185\u3002'),\n );\n }\n const shortDescription = normalizeText(\n document.app.shortDescription,\n EFFECT_RECIPE_APP_SHORT_DESCRIPTION_MAX_CODE_POINTS,\n );\n if (!shortDescription) {\n errors.push(\n createError(\n 'invalid_length',\n 'app.shortDescription',\n 'app.shortDescription \u4E0D\u80FD\u4E3A\u7A7A\uFF0C\u4E14\u957F\u5EA6\u5FC5\u987B\u5728\u5141\u8BB8\u8303\u56F4\u5185\u3002',\n ),\n );\n }\n const iconId = normalizeText(document.app.iconId, EFFECT_RECIPE_APP_ICON_ID_MAX_LENGTH);\n if (!iconId || !EFFECT_RECIPE_STABLE_ID_REGEX.test(iconId)) {\n errors.push(createError('invalid_id', 'app.iconId', 'app.iconId \u5FC5\u987B\u662F\u7A33\u5B9A\u6807\u8BC6\u7B26\u3002'));\n }\n const order = normalizeNonNegativeInteger(document.app.order, EFFECT_RECIPE_APP_ORDER_MAX);\n if (order === null) {\n errors.push(\n createError(\n 'out_of_range',\n 'app.order',\n `app.order \u5FC5\u987B\u662F 0 \u5230 ${EFFECT_RECIPE_APP_ORDER_MAX} \u7684\u5B89\u5168\u6574\u6570\u3002`,\n ),\n );\n }\n if (\n label &&\n shortDescription &&\n iconId &&\n EFFECT_RECIPE_STABLE_ID_REGEX.test(iconId) &&\n order !== null\n ) {\n app = {\n label,\n shortDescription,\n iconId,\n order,\n };\n }\n }\n\n const rawTracks = document.tracks;\n const tracks: EffectRecipeTrackDefinition[] = [];\n const seenTrackIds = new Set<string>();\n if (!Array.isArray(rawTracks)) {\n errors.push(createError('invalid_type', 'tracks', 'tracks \u5FC5\u987B\u662F\u6570\u7EC4\u3002'));\n } else if (rawTracks.length === 0) {\n errors.push(createError('invalid_length', 'tracks', 'tracks \u81F3\u5C11\u9700\u8981\u4E00\u4E2A track\u3002'));\n } else if (rawTracks.length > EFFECT_RECIPE_MAX_TRACKS) {\n errors.push(\n createError('too_many_items', 'tracks', `tracks \u6570\u91CF\u4E0D\u80FD\u8D85\u8FC7 ${EFFECT_RECIPE_MAX_TRACKS}\u3002`),\n );\n } else {\n rawTracks.forEach((rawTrack, trackIndex) => {\n const trackPath = `tracks[${trackIndex}]`;\n if (!isRecord(rawTrack)) {\n errors.push(createError('invalid_type', trackPath, 'track \u5FC5\u987B\u662F\u5BF9\u8C61\u3002'));\n return;\n }\n\n const trackId = normalizeText(rawTrack.id, EFFECT_RECIPE_TRACK_ID_MAX_LENGTH);\n if (!trackId || !EFFECT_RECIPE_STABLE_ID_REGEX.test(trackId)) {\n errors.push(createError('invalid_id', `${trackPath}.id`, 'track id \u5FC5\u987B\u662F\u7A33\u5B9A\u6807\u8BC6\u7B26\u3002'));\n } else if (seenTrackIds.has(trackId)) {\n errors.push(\n createError('duplicate_track_id', `${trackPath}.id`, `\u91CD\u590D\u7684 track id: ${trackId}\u3002`),\n );\n } else {\n seenTrackIds.add(trackId);\n }\n\n const atMs = normalizeNonNegativeInteger(rawTrack.atMs, EFFECT_RECIPE_MAX_DURATION_MS);\n if (atMs === null) {\n errors.push(\n createError(\n 'out_of_range',\n `${trackPath}.atMs`,\n `track.atMs \u5FC5\u987B\u662F 0 \u5230 ${EFFECT_RECIPE_MAX_DURATION_MS} \u7684\u5B89\u5168\u6574\u6570\u3002`,\n ),\n );\n }\n\n const trackDurationMs = normalizeNonNegativeInteger(\n rawTrack.durationMs,\n EFFECT_RECIPE_MAX_DURATION_MS,\n );\n if (trackDurationMs === null) {\n errors.push(\n createError(\n 'out_of_range',\n `${trackPath}.durationMs`,\n `track.durationMs \u5FC5\u987B\u662F 0 \u5230 ${EFFECT_RECIPE_MAX_DURATION_MS} \u7684\u5B89\u5168\u6574\u6570\u3002`,\n ),\n );\n }\n\n if (\n durationMs !== null &&\n atMs !== null &&\n trackDurationMs !== null &&\n atMs + trackDurationMs > durationMs\n ) {\n errors.push(\n createError(\n 'out_of_range',\n `${trackPath}.durationMs`,\n 'track \u6267\u884C\u533A\u95F4\u4E0D\u80FD\u8D85\u51FA recipe.durationMs\u3002',\n ),\n );\n }\n\n if (\n rawTrack.target !== undefined &&\n !EFFECT_TARGETS.some((target) => target === rawTrack.target)\n ) {\n errors.push(createError('invalid_enum', 'tracks.target', '\u975E\u6CD5\u7279\u6548\u4F5C\u7528\u76EE\u6807\u3002'));\n }\n const primitiveId = normalizeText(\n rawTrack.primitiveId,\n EFFECT_RECIPE_PRIMITIVE_ID_MAX_LENGTH,\n );\n if (!primitiveId || !EFFECT_RECIPE_STABLE_ID_REGEX.test(primitiveId)) {\n errors.push(\n createError(\n 'invalid_id',\n `${trackPath}.primitiveId`,\n 'track primitiveId \u5FC5\u987B\u662F\u7A33\u5B9A\u6807\u8BC6\u7B26\u3002',\n ),\n );\n }\n\n if (typeof rawTrack.enabled !== 'boolean') {\n errors.push(\n createError('invalid_type', `${trackPath}.enabled`, 'track.enabled \u5FC5\u987B\u662F\u5E03\u5C14\u503C\u3002'),\n );\n }\n\n const params: Record<string, RecipeValue> = {};\n if (!isRecord(rawTrack.params)) {\n errors.push(\n createError('invalid_type', `${trackPath}.params`, 'track.params \u5FC5\u987B\u662F\u5BF9\u8C61\u3002'),\n );\n } else {\n Object.entries(rawTrack.params).forEach(([paramName, paramValue]) => {\n const normalizedValue = parseRecipeValue(\n paramValue,\n `${trackPath}.params.${paramName}`,\n errors,\n );\n if (normalizedValue !== null) {\n params[paramName] = normalizedValue;\n }\n });\n }\n\n if (\n trackId &&\n EFFECT_RECIPE_STABLE_ID_REGEX.test(trackId) &&\n atMs !== null &&\n trackDurationMs !== null &&\n primitiveId &&\n EFFECT_RECIPE_STABLE_ID_REGEX.test(primitiveId) &&\n typeof rawTrack.enabled === 'boolean' &&\n isRecord(rawTrack.params)\n ) {\n tracks.push({\n id: trackId,\n atMs,\n durationMs: trackDurationMs,\n ...(rawTrack.target === undefined ? {} : { target: rawTrack.target as EffectTarget }),\n primitiveId,\n params,\n enabled: rawTrack.enabled,\n });\n }\n });\n }\n\n if (\n errors.length > 0 ||\n !id ||\n !name ||\n !description ||\n !isEffectRecipeScope(scope) ||\n !isEffectRecipeCategory(category) ||\n durationMs === null ||\n commitAtMs === null ||\n !app\n ) {\n return { definition: null, errors };\n }\n\n return {\n definition: {\n schemaVersion: EFFECT_RECIPE_SCHEMA_VERSION,\n id,\n name,\n description,\n scope,\n category,\n durationMs,\n commitAtMs,\n app,\n tracks,\n },\n errors,\n };\n};\n\nexport const createEffectRecipeValidationError = createError;\n", "import type { EffectRecipeScope } from './schema.js';\n\nexport const EFFECT_PRIMITIVE_CATEGORIES = [\n 'content',\n 'screen',\n 'camera',\n 'shader',\n 'particle',\n 'ui',\n 'audio',\n] as const;\nexport const EFFECT_PRIMITIVE_PARAM_TYPES = ['string', 'number', 'boolean', 'number[]'] as const;\nexport const EFFECT_PRIMITIVE_PREVIEW_SUPPORT = ['full', 'milestone', 'replay-only'] as const;\n\nexport type EffectPrimitiveCategory = (typeof EFFECT_PRIMITIVE_CATEGORIES)[number];\nexport type EffectPrimitiveParamType = (typeof EFFECT_PRIMITIVE_PARAM_TYPES)[number];\nexport type EffectPrimitivePreviewSupport = (typeof EFFECT_PRIMITIVE_PREVIEW_SUPPORT)[number];\n\nexport interface EffectPrimitiveParamDescriptor {\n name: string;\n label: string;\n type: EffectPrimitiveParamType;\n required: boolean;\n min?: number;\n max?: number;\n minLength?: number;\n maxLength?: number;\n arrayMinLength?: number;\n arrayMaxLength?: number;\n options?: readonly (string | number | boolean)[];\n tuningPathAllowed?: boolean;\n}\n\nexport interface EffectPrimitiveDescriptor {\n id: string;\n label: string;\n category: EffectPrimitiveCategory;\n scopes: readonly EffectRecipeScope[];\n paramsSchema: readonly EffectPrimitiveParamDescriptor[];\n previewSupport: EffectPrimitivePreviewSupport;\n conflicts: readonly string[];\n maxInstances: number;\n}\n\nexport class EffectPrimitiveRegistry {\n private readonly descriptors: readonly EffectPrimitiveDescriptor[];\n private readonly descriptorById: ReadonlyMap<string, EffectPrimitiveDescriptor>;\n\n constructor(descriptors: readonly EffectPrimitiveDescriptor[]) {\n const descriptorById = new Map<string, EffectPrimitiveDescriptor>();\n for (const descriptor of descriptors) {\n if (descriptorById.has(descriptor.id)) {\n throw new Error(`\u91CD\u590D\u7684 primitive descriptor: ${descriptor.id}`);\n }\n descriptorById.set(descriptor.id, descriptor);\n }\n this.descriptors = [...descriptors];\n this.descriptorById = descriptorById;\n }\n\n all(): readonly EffectPrimitiveDescriptor[] {\n return this.descriptors;\n }\n\n get(id: string): EffectPrimitiveDescriptor | null {\n return this.descriptorById.get(id) ?? null;\n }\n\n listByScope(scope: EffectRecipeScope): readonly EffectPrimitiveDescriptor[] {\n return this.descriptors.filter((descriptor) => descriptor.scopes.includes(scope));\n }\n}\n", "const isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\nimport {\n type EffectPrimitiveDescriptor,\n type EffectPrimitiveParamDescriptor,\n type EffectPrimitiveRegistry,\n} from './primitives.js';\nimport {\n createEffectRecipeValidationError,\n isEffectRecipeTuningPathReference,\n validateEffectRecipeDefinition,\n type EffectRecipeAppMetadata,\n type EffectRecipeCategory,\n type EffectRecipeDefinition,\n type EffectRecipeId,\n type EffectRecipeScope,\n type EffectRecipeTuningPathReference,\n type EffectRecipeValidationError,\n type RecipeValue,\n type ResolvedRecipeValue,\n} from './schema.js';\n\nconst hasOwn = (value: Record<string, unknown>, key: string): boolean =>\n Object.prototype.hasOwnProperty.call(value, key);\n\nconst prefixPath = (prefix: string, path: string): string => {\n if (!prefix) {\n return path;\n }\n if (!path) {\n return prefix;\n }\n if (path.startsWith('[')) {\n return `${prefix}${path}`;\n }\n return `${prefix}.${path}`;\n};\n\nconst normalizeString = (value: string): string => value.trim();\n\nexport type EffectRecipeSource = 'builtin' | 'custom';\n\nexport interface EffectRecipeManifestEntry {\n source: EffectRecipeSource;\n definition: unknown;\n}\n\nexport interface EffectRecipeCatalogEntry {\n id: EffectRecipeId;\n name: string;\n description: string;\n scope: EffectRecipeScope;\n category: EffectRecipeCategory;\n durationMs: number;\n commitAtMs: number;\n source: EffectRecipeSource;\n app: EffectRecipeAppMetadata;\n trackCount: number;\n}\n\nexport interface EffectRecipeRegistration {\n source: EffectRecipeSource;\n definition: EffectRecipeDefinition;\n catalog: EffectRecipeCatalogEntry;\n}\n\nexport interface EffectRecipeManifestValidationResult {\n entries: readonly EffectRecipeRegistration[];\n errors: readonly EffectRecipeValidationError[];\n}\n\nexport interface EffectRecipeSingleValidationResult {\n entry: EffectRecipeRegistration | null;\n errors: readonly EffectRecipeValidationError[];\n}\n\nexport class EffectRecipeRegistryError extends Error {\n constructor(public readonly errors: readonly EffectRecipeValidationError[]) {\n super(errors.map((error) => `${error.path}: ${error.message}`).join('\\n'));\n this.name = 'EffectRecipeRegistryError';\n }\n}\n\nconst buildCatalog = (\n definition: EffectRecipeDefinition,\n source: EffectRecipeSource,\n): EffectRecipeCatalogEntry => ({\n id: definition.id,\n name: definition.name,\n description: definition.description,\n scope: definition.scope,\n category: definition.category,\n durationMs: definition.durationMs,\n commitAtMs: definition.commitAtMs,\n source,\n app: definition.app,\n trackCount: definition.tracks.length,\n});\n\nconst sortRegistrations = (\n entries: readonly EffectRecipeRegistration[],\n): EffectRecipeRegistration[] =>\n [...entries].sort((left, right) => {\n if (left.catalog.app.order !== right.catalog.app.order) {\n return left.catalog.app.order - right.catalog.app.order;\n }\n return left.catalog.id.localeCompare(right.catalog.id, 'zh-CN');\n });\n\ninterface EffectPrimitiveParamValidationOptions {\n allowTuningPath: boolean;\n pathPrefix?: string;\n}\n\ntype PrimitiveParamValidationResult<TValue> = {\n params: Record<string, TValue> | null;\n errors: readonly EffectRecipeValidationError[];\n};\n\nconst validateStringValue = (\n value: string,\n descriptor: EffectPrimitiveParamDescriptor,\n path: string,\n errors: EffectRecipeValidationError[],\n): string | null => {\n const normalized = normalizeString(value);\n if (descriptor.name === 'color' && !/^#[0-9a-f]{6}$/i.test(normalized)) {\n errors.push(\n createEffectRecipeValidationError('invalid_param_value', path, '\u989C\u8272\u5FC5\u987B\u662F #RRGGBB\u3002'),\n );\n return null;\n }\n if (descriptor.minLength !== undefined && normalized.length < descriptor.minLength) {\n errors.push(\n createEffectRecipeValidationError(\n 'invalid_param_value',\n path,\n `${descriptor.name} \u5B57\u7B26\u4E32\u957F\u5EA6\u4E0D\u80FD\u5C0F\u4E8E ${descriptor.minLength}\u3002`,\n ),\n );\n return null;\n }\n if (descriptor.maxLength !== undefined && normalized.length > descriptor.maxLength) {\n errors.push(\n createEffectRecipeValidationError(\n 'invalid_param_value',\n path,\n `${descriptor.name} \u5B57\u7B26\u4E32\u957F\u5EA6\u4E0D\u80FD\u5927\u4E8E ${descriptor.maxLength}\u3002`,\n ),\n );\n return null;\n }\n if (descriptor.options && !descriptor.options.includes(normalized)) {\n errors.push(\n createEffectRecipeValidationError(\n 'invalid_param_value',\n path,\n `${descriptor.name} \u5FC5\u987B\u662F ${descriptor.options.join('\u3001')} \u4E4B\u4E00\u3002`,\n ),\n );\n return null;\n }\n return normalized;\n};\n\nconst validateNumberValue = (\n value: number,\n descriptor: EffectPrimitiveParamDescriptor,\n path: string,\n errors: EffectRecipeValidationError[],\n): number | null => {\n if (!Number.isFinite(value)) {\n errors.push(\n createEffectRecipeValidationError(\n 'invalid_param_type',\n path,\n `${descriptor.name} \u5FC5\u987B\u662F\u6709\u9650\u6570\u5B57\u3002`,\n ),\n );\n return null;\n }\n if (descriptor.min !== undefined && value < descriptor.min) {\n errors.push(\n createEffectRecipeValidationError(\n 'invalid_param_value',\n path,\n `${descriptor.name} \u4E0D\u80FD\u5C0F\u4E8E ${descriptor.min}\u3002`,\n ),\n );\n return null;\n }\n if (descriptor.max !== undefined && value > descriptor.max) {\n errors.push(\n createEffectRecipeValidationError(\n 'invalid_param_value',\n path,\n `${descriptor.name} \u4E0D\u80FD\u5927\u4E8E ${descriptor.max}\u3002`,\n ),\n );\n return null;\n }\n if (descriptor.options && !descriptor.options.includes(value)) {\n errors.push(\n createEffectRecipeValidationError(\n 'invalid_param_value',\n path,\n `${descriptor.name} \u4E0D\u5728\u5141\u8BB8\u7684\u679A\u4E3E\u8303\u56F4\u5185\u3002`,\n ),\n );\n return null;\n }\n return value;\n};\n\nconst validateBooleanValue = (\n value: boolean,\n descriptor: EffectPrimitiveParamDescriptor,\n path: string,\n errors: EffectRecipeValidationError[],\n): boolean | null => {\n if (descriptor.options && !descriptor.options.includes(value)) {\n errors.push(\n createEffectRecipeValidationError(\n 'invalid_param_value',\n path,\n `${descriptor.name} \u4E0D\u5728\u5141\u8BB8\u7684\u679A\u4E3E\u8303\u56F4\u5185\u3002`,\n ),\n );\n return null;\n }\n return value;\n};\n\nconst validateNumberArrayValue = (\n value: number[],\n descriptor: EffectPrimitiveParamDescriptor,\n path: string,\n errors: EffectRecipeValidationError[],\n): number[] | null => {\n if (!value.every((entry) => typeof entry === 'number' && Number.isFinite(entry))) {\n errors.push(\n createEffectRecipeValidationError(\n 'invalid_param_type',\n path,\n `${descriptor.name} \u5FC5\u987B\u662F\u6709\u9650\u6570\u5B57\u6570\u7EC4\u3002`,\n ),\n );\n return null;\n }\n if (descriptor.arrayMinLength !== undefined && value.length < descriptor.arrayMinLength) {\n errors.push(\n createEffectRecipeValidationError(\n 'invalid_param_value',\n path,\n `${descriptor.name} \u6570\u7EC4\u957F\u5EA6\u4E0D\u80FD\u5C0F\u4E8E ${descriptor.arrayMinLength}\u3002`,\n ),\n );\n return null;\n }\n if (descriptor.arrayMaxLength !== undefined && value.length > descriptor.arrayMaxLength) {\n errors.push(\n createEffectRecipeValidationError(\n 'invalid_param_value',\n path,\n `${descriptor.name} \u6570\u7EC4\u957F\u5EA6\u4E0D\u80FD\u5927\u4E8E ${descriptor.arrayMaxLength}\u3002`,\n ),\n );\n return null;\n }\n if (\n (descriptor.min !== undefined || descriptor.max !== undefined) &&\n value.some(\n (entry) =>\n (descriptor.min !== undefined && entry < descriptor.min) ||\n (descriptor.max !== undefined && entry > descriptor.max),\n )\n ) {\n errors.push(\n createEffectRecipeValidationError(\n 'invalid_param_value',\n path,\n `${descriptor.name} \u6570\u7EC4\u5143\u7D20\u8D85\u51FA\u5141\u8BB8\u8303\u56F4\u3002`,\n ),\n );\n return null;\n }\n return [...value];\n};\n\nconst validateParamValue = <TValue extends RecipeValue | ResolvedRecipeValue>(\n value: TValue,\n descriptor: EffectPrimitiveParamDescriptor,\n path: string,\n errors: EffectRecipeValidationError[],\n options: EffectPrimitiveParamValidationOptions,\n): TValue | null => {\n if (isEffectRecipeTuningPathReference(value)) {\n if (!options.allowTuningPath || descriptor.tuningPathAllowed !== true) {\n errors.push(\n createEffectRecipeValidationError(\n 'invalid_tuning_path',\n path,\n `${descriptor.name} \u4E0D\u5141\u8BB8\u4F7F\u7528 tuningPath \u5F15\u7528\u3002`,\n ),\n );\n return null;\n }\n return { tuningPath: value.tuningPath } as TValue;\n }\n\n switch (descriptor.type) {\n case 'string': {\n if (typeof value !== 'string') {\n errors.push(\n createEffectRecipeValidationError(\n 'invalid_param_type',\n path,\n `${descriptor.name} \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u3002`,\n ),\n );\n return null;\n }\n const normalized = validateStringValue(value, descriptor, path, errors);\n return normalized as TValue | null;\n }\n case 'number': {\n if (typeof value !== 'number') {\n errors.push(\n createEffectRecipeValidationError(\n 'invalid_param_type',\n path,\n `${descriptor.name} \u5FC5\u987B\u662F\u6570\u5B57\u3002`,\n ),\n );\n return null;\n }\n const normalized = validateNumberValue(value, descriptor, path, errors);\n return normalized as TValue | null;\n }\n case 'boolean': {\n if (typeof value !== 'boolean') {\n errors.push(\n createEffectRecipeValidationError(\n 'invalid_param_type',\n path,\n `${descriptor.name} \u5FC5\u987B\u662F\u5E03\u5C14\u503C\u3002`,\n ),\n );\n return null;\n }\n const normalized = validateBooleanValue(value, descriptor, path, errors);\n return normalized as TValue | null;\n }\n case 'number[]': {\n if (!Array.isArray(value)) {\n errors.push(\n createEffectRecipeValidationError(\n 'invalid_param_type',\n path,\n `${descriptor.name} \u5FC5\u987B\u662F\u6570\u5B57\u6570\u7EC4\u3002`,\n ),\n );\n return null;\n }\n const normalized = validateNumberArrayValue(value, descriptor, path, errors);\n return normalized as TValue | null;\n }\n }\n};\n\nconst validatePrimitiveParamsInternal = <TValue extends RecipeValue | ResolvedRecipeValue>(\n descriptor: EffectPrimitiveDescriptor,\n params: unknown,\n options: EffectPrimitiveParamValidationOptions,\n): PrimitiveParamValidationResult<TValue> => {\n const errors: EffectRecipeValidationError[] = [];\n const pathPrefix = options.pathPrefix ?? 'params';\n if (!isRecord(params)) {\n return {\n params: null,\n errors: [\n createEffectRecipeValidationError('invalid_type', pathPrefix, 'params \u5FC5\u987B\u662F\u5BF9\u8C61\u3002'),\n ],\n };\n }\n\n const normalizedParams: Record<string, TValue> = {};\n const descriptorMap = new Map(descriptor.paramsSchema.map((item) => [item.name, item]));\n\n Object.keys(params).forEach((key) => {\n if (!descriptorMap.has(key)) {\n errors.push(\n createEffectRecipeValidationError(\n 'unknown_param',\n `${pathPrefix}.${key}`,\n `\u672A\u77E5\u53C2\u6570: ${key}\u3002`,\n ),\n );\n }\n });\n\n for (const paramDescriptor of descriptor.paramsSchema) {\n const paramPath = `${pathPrefix}.${paramDescriptor.name}`;\n const exists = hasOwn(params, paramDescriptor.name);\n if (!exists) {\n if (paramDescriptor.required) {\n errors.push(\n createEffectRecipeValidationError(\n 'missing_param',\n paramPath,\n `\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570: ${paramDescriptor.name}\u3002`,\n ),\n );\n }\n continue;\n }\n\n const rawValue = params[paramDescriptor.name];\n const normalizedValue = validateParamValue(\n rawValue as TValue,\n paramDescriptor,\n paramPath,\n errors,\n options,\n );\n if (normalizedValue !== null) {\n normalizedParams[paramDescriptor.name] = normalizedValue;\n }\n }\n\n return { params: errors.length === 0 ? normalizedParams : null, errors };\n};\n\nexport const validateEffectRecipeTrackParams = (\n descriptor: EffectPrimitiveDescriptor,\n params: unknown,\n pathPrefix = 'params',\n): PrimitiveParamValidationResult<RecipeValue> =>\n validatePrimitiveParamsInternal<RecipeValue>(descriptor, params, {\n allowTuningPath: true,\n pathPrefix,\n });\n\nexport const validateResolvedEffectRecipeTrackParams = (\n descriptor: EffectPrimitiveDescriptor,\n params: unknown,\n pathPrefix = 'params',\n): PrimitiveParamValidationResult<ResolvedRecipeValue> =>\n validatePrimitiveParamsInternal<ResolvedRecipeValue>(descriptor, params, {\n allowTuningPath: false,\n pathPrefix,\n });\n\nexport const validateEffectRecipeManifest = (\n entries: readonly EffectRecipeManifestEntry[],\n primitiveRegistry: EffectPrimitiveRegistry,\n): EffectRecipeManifestValidationResult => {\n const errors: EffectRecipeValidationError[] = [];\n const provisional: EffectRecipeRegistration[] = [];\n const seenRecipeIds = new Set<string>();\n\n entries.forEach((entry, index) => {\n const definitionResult = validateEffectRecipeDefinition(entry.definition);\n const entryPrefix = `recipes[${index}]`;\n if (!definitionResult.definition) {\n errors.push(\n ...definitionResult.errors.map((error) => ({\n ...error,\n path: prefixPath(entryPrefix, error.path),\n })),\n );\n return;\n }\n\n const definition = definitionResult.definition;\n if (seenRecipeIds.has(definition.id)) {\n errors.push(\n createEffectRecipeValidationError(\n 'duplicate_recipe_id',\n `${entryPrefix}.id`,\n `\u91CD\u590D\u7684 recipe id: ${definition.id}\u3002`,\n ),\n );\n return;\n }\n seenRecipeIds.add(definition.id);\n\n definition.tracks.forEach((track, trackIndex) => {\n const trackPath = `${entryPrefix}.tracks[${trackIndex}]`;\n const descriptor = primitiveRegistry.get(track.primitiveId);\n if (!descriptor) {\n errors.push(\n createEffectRecipeValidationError(\n 'unknown_primitive',\n `${trackPath}.primitiveId`,\n `\u672A\u77E5 primitive: ${track.primitiveId}\u3002`,\n ),\n );\n return;\n }\n\n if (!descriptor.scopes.includes(definition.scope)) {\n errors.push(\n createEffectRecipeValidationError(\n 'unsupported_scope',\n `${trackPath}.primitiveId`,\n `primitive ${track.primitiveId} \u4E0D\u652F\u6301 ${definition.scope} scope\u3002`,\n ),\n );\n }\n\n const paramsResult = validateEffectRecipeTrackParams(\n descriptor,\n track.params,\n `${trackPath}.params`,\n );\n errors.push(...paramsResult.errors);\n });\n\n if (!errors.some((error) => error.path.startsWith(entryPrefix))) {\n provisional.push({\n source: entry.source,\n definition,\n catalog: buildCatalog(definition, entry.source),\n });\n }\n });\n\n return {\n entries: sortRegistrations(provisional),\n errors,\n };\n};\n\nexport class EffectRecipeRegistry {\n private readonly entries: readonly EffectRecipeRegistration[];\n private readonly entryById: ReadonlyMap<string, EffectRecipeRegistration>;\n\n constructor(\n manifestEntries: readonly EffectRecipeManifestEntry[],\n private readonly primitiveRegistry: EffectPrimitiveRegistry,\n ) {\n const result = validateEffectRecipeManifest(manifestEntries, primitiveRegistry);\n if (result.errors.length > 0) {\n throw new EffectRecipeRegistryError(result.errors);\n }\n this.entries = result.entries;\n this.entryById = new Map(result.entries.map((entry) => [entry.definition.id, entry]));\n }\n\n all(): readonly EffectRecipeRegistration[] {\n return this.entries;\n }\n\n catalog(): readonly EffectRecipeCatalogEntry[] {\n return this.entries.map((entry) => entry.catalog);\n }\n\n get(recipeId: EffectRecipeId): EffectRecipeRegistration | null {\n return this.entryById.get(recipeId) ?? null;\n }\n\n listByScope(scope: EffectRecipeScope): readonly EffectRecipeRegistration[] {\n return this.entries.filter((entry) => entry.definition.scope === scope);\n }\n\n listByCategory(category: EffectRecipeCategory): readonly EffectRecipeRegistration[] {\n return this.entries.filter((entry) => entry.definition.category === category);\n }\n\n validate(\n definition: unknown,\n source: EffectRecipeSource = 'custom',\n ): EffectRecipeSingleValidationResult {\n const result = validateEffectRecipeManifest(\n [\n {\n source,\n definition,\n },\n ],\n this.primitiveRegistry,\n );\n\n return {\n entry: result.errors.length === 0 ? (result.entries[0] ?? null) : null,\n errors: result.errors,\n };\n }\n}\n\nexport const resolveEffectRecipePrimitiveDescriptor = (\n recipe: EffectRecipeDefinition,\n trackIndex: number,\n primitiveRegistry: EffectPrimitiveRegistry,\n): EffectPrimitiveDescriptor | null =>\n primitiveRegistry.get(recipe.tracks[trackIndex]?.primitiveId ?? '');\n\nexport type { EffectRecipeTuningPathReference };\n", "import type { EffectPrimitiveDescriptor } from './primitives.js';\nimport type {\n EffectRecipeDefinition,\n EffectRecipeId,\n EffectRecipeTrackDefinition,\n ResolvedRecipeValue,\n} from './schema.js';\n\nexport type EffectPrimitiveResolvedParams = Record<string, ResolvedRecipeValue>;\nexport interface EffectPrimitiveRuntimeHandle {\n cleanup(): void;\n completed?: Promise<void>;\n cleanupPolicy?: 'track-end' | 'recipe-end';\n}\nexport type EffectPrimitiveCleanup = void | (() => void) | EffectPrimitiveRuntimeHandle;\nexport type EffectPrimitiveExecuteResult = EffectPrimitiveCleanup | Promise<EffectPrimitiveCleanup>;\n\nexport interface EffectPrimitiveExecutionContext<TRuntimeContext = unknown> {\n recipeId: EffectRecipeId;\n recipe: EffectRecipeDefinition;\n track: EffectRecipeTrackDefinition;\n primitive: EffectPrimitiveDescriptor;\n runtimeContext: TRuntimeContext;\n}\n\nexport interface EffectPrimitiveRuntime<TRuntimeContext = unknown> {\n readonly primitiveId: string;\n readonly consumedParams?: readonly string[];\n execute(\n context: EffectPrimitiveExecutionContext<TRuntimeContext>,\n params: EffectPrimitiveResolvedParams,\n signal: AbortSignal,\n ): EffectPrimitiveExecuteResult;\n}\n\nexport class EffectPrimitiveRuntimeRegistry<TRuntimeContext = unknown> {\n private readonly runtimes = new Map<string, EffectPrimitiveRuntime<TRuntimeContext>>();\n\n register(runtime: EffectPrimitiveRuntime<TRuntimeContext>): void {\n if (this.runtimes.has(runtime.primitiveId)) {\n throw new Error(`\u91CD\u590D\u7684 effect primitive runtime: ${runtime.primitiveId}`);\n }\n this.runtimes.set(runtime.primitiveId, runtime);\n }\n\n get(primitiveId: string): EffectPrimitiveRuntime<TRuntimeContext> | null {\n return this.runtimes.get(primitiveId) ?? null;\n }\n\n listIds(): readonly string[] {\n return [...this.runtimes.keys()].sort((left, right) => left.localeCompare(right, 'zh-CN'));\n }\n}\n", "import { type EffectPrimitiveDescriptor, type EffectPrimitiveRegistry } from './primitives.js';\nimport { validateResolvedEffectRecipeTrackParams, type EffectRecipeRegistry } from './registry.js';\nimport {\n type EffectRecipeValidationError,\n isEffectRecipeTuningPathReference,\n isResolvedRecipeValue,\n type EffectRecipeDefinition,\n type EffectRecipeId,\n type EffectRecipeTrackDefinition,\n type EffectRecipeTuningPathReference,\n type ResolvedRecipeValue,\n} from './schema.js';\nimport type {\n EffectPrimitiveExecutionContext,\n EffectPrimitiveResolvedParams,\n EffectPrimitiveRuntime,\n} from './EffectPrimitiveRuntimeRegistry.js';\nimport { EffectPrimitiveRuntimeRegistry } from './EffectPrimitiveRuntimeRegistry.js';\n\nexport type EffectRecipeExecutorErrorCode =\n | 'invalid_params'\n | 'runtime_error'\n | 'tuning_resolution_failed'\n | 'unknown_primitive'\n | 'unknown_recipe'\n | 'unknown_runtime';\n\nexport interface EffectRecipeExecutorScheduler {\n setTimeout(callback: () => void, delayMs: number): unknown;\n clearTimeout(handle: unknown): void;\n}\n\nexport interface EffectRecipeTuningResolutionContext<TRuntimeContext> {\n recipe: EffectRecipeDefinition;\n track: EffectRecipeTrackDefinition;\n primitive: EffectPrimitiveDescriptor;\n paramName: string;\n runtimeContext: TRuntimeContext;\n}\n\nexport interface EffectRecipeTrackPlanItem<TRuntimeContext> {\n track: EffectRecipeTrackDefinition;\n primitive: EffectPrimitiveDescriptor;\n runtime: EffectPrimitiveRuntime<TRuntimeContext>;\n params: EffectPrimitiveResolvedParams;\n executionContext: EffectPrimitiveExecutionContext<TRuntimeContext>;\n}\n\nexport interface EffectRecipeExecutionOutcome {\n recipeId: EffectRecipeId;\n status: 'completed' | 'aborted';\n committed: boolean;\n}\n\nexport interface EffectRecipeExecutionHandle {\n recipe: EffectRecipeDefinition;\n signal: AbortSignal;\n done: Promise<EffectRecipeExecutionOutcome>;\n abort(reason?: string): void;\n}\n\nexport interface EffectRecipeExecutorOptions<TRuntimeContext> {\n runtimeRegistry: EffectPrimitiveRuntimeRegistry<TRuntimeContext>;\n resolveTuningPath: (\n reference: EffectRecipeTuningPathReference,\n context: EffectRecipeTuningResolutionContext<TRuntimeContext>,\n ) => ResolvedRecipeValue;\n scheduler: EffectRecipeExecutorScheduler;\n recipeRegistry: Pick<EffectRecipeRegistry, 'get' | 'validate'>;\n primitiveRegistry: EffectPrimitiveRegistry;\n}\n\nexport interface ExecuteEffectRecipeOptions<TRuntimeContext> {\n recipe: EffectRecipeId | EffectRecipeDefinition;\n runtimeContext: TRuntimeContext;\n signal?: AbortSignal;\n onCommit?: (recipe: EffectRecipeDefinition) => void;\n onDone?: (outcome: EffectRecipeExecutionOutcome) => void;\n}\n\nconst compareTracks = (\n left: EffectRecipeTrackDefinition,\n right: EffectRecipeTrackDefinition,\n): number => {\n if (left.atMs !== right.atMs) {\n return left.atMs - right.atMs;\n }\n return left.id.localeCompare(right.id, 'zh-CN');\n};\n\nconst isRecipeDefinition = (\n value: EffectRecipeId | EffectRecipeDefinition,\n): value is EffectRecipeDefinition => typeof value !== 'string';\n\nconst resolveTrackIdFromValidationErrors = (\n recipe: EffectRecipeDefinition,\n errors: readonly EffectRecipeValidationError[],\n): string | undefined => {\n const trackPath = errors.find((error) => /^recipes\\[0\\]\\.tracks\\[\\d+\\]/.test(error.path))?.path;\n if (!trackPath) {\n return undefined;\n }\n\n const match = /^recipes\\[0\\]\\.tracks\\[(\\d+)\\]/.exec(trackPath);\n const trackIndex = match ? Number.parseInt(match[1] ?? '', 10) : Number.NaN;\n if (!Number.isSafeInteger(trackIndex) || trackIndex < 0) {\n return undefined;\n }\n\n return recipe.tracks[trackIndex]?.id;\n};\n\nexport class EffectRecipeExecutorError extends Error {\n readonly cause: unknown;\n\n constructor(\n public readonly code: EffectRecipeExecutorErrorCode,\n public readonly recipeId: EffectRecipeId,\n message: string,\n options: {\n trackId?: string;\n validationErrors?: readonly EffectRecipeValidationError[];\n cause?: unknown;\n } = {},\n ) {\n super(message);\n this.name = 'EffectRecipeExecutorError';\n this.trackId = options.trackId;\n this.validationErrors = options.validationErrors ?? [];\n this.cause = options.cause;\n }\n\n readonly trackId?: string;\n readonly validationErrors: readonly EffectRecipeValidationError[];\n}\n\nexport class EffectRecipeExecutor<TRuntimeContext = unknown> {\n private readonly scheduler: EffectRecipeExecutorScheduler;\n private readonly recipeRegistry: Pick<EffectRecipeRegistry, 'get' | 'validate'>;\n private readonly primitiveRegistry: EffectPrimitiveRegistry;\n\n constructor(private readonly options: EffectRecipeExecutorOptions<TRuntimeContext>) {\n this.scheduler = options.scheduler;\n this.recipeRegistry = options.recipeRegistry;\n this.primitiveRegistry = options.primitiveRegistry;\n }\n\n buildPlan(\n recipeInput: EffectRecipeId | EffectRecipeDefinition,\n runtimeContext: TRuntimeContext,\n ): readonly EffectRecipeTrackPlanItem<TRuntimeContext>[] {\n const recipe = this.resolveRecipe(recipeInput);\n return recipe.tracks\n .filter((track) => track.enabled)\n .slice()\n .sort(compareTracks)\n .map((track) => this.resolveTrackPlanItem(recipe, track, runtimeContext));\n }\n\n execute(runOptions: ExecuteEffectRecipeOptions<TRuntimeContext>): EffectRecipeExecutionHandle {\n const recipe = this.resolveRecipe(runOptions.recipe);\n const plan = this.buildPlan(recipe, runOptions.runtimeContext);\n const controller = new AbortController();\n const timerHandles: unknown[] = [];\n const activeCleanups = new Map<string, () => void>();\n const expiredTracks = new Set<string>();\n const trackControllers = new Map<string, AbortController>();\n const recipeEndTracks = new Set<string>();\n const pendingCleanupPromises = new Set<Promise<void>>();\n\n let committed = false;\n let finished = false;\n let detachExternalSignal: (() => void) | null = null;\n\n let resolveDone!: (outcome: EffectRecipeExecutionOutcome) => void;\n let rejectDone!: (error: EffectRecipeExecutorError) => void;\n const done = new Promise<EffectRecipeExecutionOutcome>((resolve, reject) => {\n resolveDone = resolve;\n rejectDone = reject;\n });\n\n const clearTimers = (): void => {\n while (timerHandles.length > 0) {\n this.scheduler.clearTimeout(timerHandles.pop()!);\n }\n };\n\n const cleanupTrack = (id: string): void => {\n expiredTracks.add(id);\n trackControllers.get(id)?.abort('track-ended');\n trackControllers.delete(id);\n const cleanup = activeCleanups.get(id);\n activeCleanups.delete(id);\n cleanup?.();\n };\n const flushCleanups = (): void => {\n for (const id of [...trackControllers.keys()]) {\n try {\n cleanupTrack(id);\n } catch {\n /* Continue releasing remaining tracks. */\n }\n }\n };\n\n const finalize = (status: 'completed' | 'aborted', error?: EffectRecipeExecutorError): void => {\n if (finished) {\n return;\n }\n\n finished = true;\n clearTimers();\n detachExternalSignal?.();\n if (status === 'aborted' && !controller.signal.aborted) {\n controller.abort(error?.message ?? 'effect-recipe-aborted');\n }\n flushCleanups();\n\n const settle = () => {\n const outcome: EffectRecipeExecutionOutcome = {\n recipeId: recipe.id,\n status,\n committed,\n };\n try {\n runOptions.onDone?.(outcome);\n } catch {\n // onDone callback failures must not corrupt executor lifecycle\n }\n if (error) {\n rejectDone(error);\n return;\n }\n resolveDone(outcome);\n };\n\n if (pendingCleanupPromises.size === 0) {\n settle();\n return;\n }\n\n void Promise.allSettled([...pendingCleanupPromises]).then(() => {\n settle();\n });\n };\n\n const requestAbort = (\n reason = 'effect-recipe-aborted',\n error?: EffectRecipeExecutorError,\n ): void => {\n if (!controller.signal.aborted) {\n controller.abort(reason);\n }\n finalize('aborted', error);\n };\n\n const fail = (\n code: EffectRecipeExecutorErrorCode,\n trackId: string | undefined,\n message: string,\n cause?: unknown,\n ): void => {\n requestAbort(\n message,\n new EffectRecipeExecutorError(\n code,\n recipe.id,\n cause instanceof Error ? `${message}: ${cause.message}` : message,\n {\n trackId,\n cause,\n },\n ),\n );\n };\n\n const registerCleanup = (\n trackId: string,\n result: ReturnType<EffectPrimitiveRuntime<TRuntimeContext>['execute']>,\n ): void => {\n const accept = (handle: Awaited<typeof result>): void => {\n if (!handle) return;\n const cleanup = typeof handle === 'function' ? handle : () => handle.cleanup();\n if (finished || expiredTracks.has(trackId) || controller.signal.aborted) {\n cleanup();\n return;\n }\n activeCleanups.set(trackId, cleanup);\n if (typeof handle !== 'function') {\n if (handle.cleanupPolicy === 'recipe-end') recipeEndTracks.add(trackId);\n void handle.completed?.catch((error: unknown) => {\n if (!finished && !expiredTracks.has(trackId))\n fail('runtime_error', trackId, 'Primitive completion failed', error);\n });\n }\n };\n if (result instanceof Promise) {\n const pending = result.then(accept).catch((error: unknown) => {\n if (!finished) fail('runtime_error', trackId, 'Primitive start failed', error);\n });\n pendingCleanupPromises.add(pending);\n void pending.finally(() => pendingCleanupPromises.delete(pending));\n } else accept(result);\n };\n\n const commit = (): void => {\n if (committed || finished || controller.signal.aborted) {\n return;\n }\n committed = true;\n try {\n runOptions.onCommit?.(recipe);\n } catch (error: unknown) {\n fail('runtime_error', undefined, 'Recipe commit callback failed', error);\n }\n };\n\n const startTrack = (planItem: EffectRecipeTrackPlanItem<TRuntimeContext>): void => {\n if (finished || controller.signal.aborted) {\n return;\n }\n try {\n const trackController = new AbortController();\n trackControllers.set(planItem.track.id, trackController);\n const result = planItem.runtime.execute(\n planItem.executionContext,\n planItem.params,\n trackController.signal,\n );\n registerCleanup(planItem.track.id, result);\n } catch (error) {\n fail(\n 'runtime_error',\n planItem.track.id,\n `Effect primitive \u540C\u6B65\u6267\u884C\u5931\u8D25: ${planItem.track.id}`,\n error,\n );\n }\n };\n\n if (runOptions.signal) {\n const abortFromCaller = (): void => {\n requestAbort(String(runOptions.signal?.reason ?? 'effect-recipe-aborted'));\n };\n if (runOptions.signal.aborted) {\n abortFromCaller();\n } else {\n runOptions.signal.addEventListener('abort', abortFromCaller, { once: true });\n detachExternalSignal = () => {\n runOptions.signal?.removeEventListener('abort', abortFromCaller);\n };\n }\n }\n\n if (!finished) {\n const groupedPlan = new Map<number, EffectRecipeTrackPlanItem<TRuntimeContext>[]>();\n for (const item of plan) {\n const existing = groupedPlan.get(item.track.atMs);\n if (existing) {\n existing.push(item);\n } else {\n groupedPlan.set(item.track.atMs, [item]);\n }\n }\n\n const scheduleTimes = [\n ...new Set([\n ...groupedPlan.keys(),\n ...plan.map((item) => item.track.atMs + item.track.durationMs),\n recipe.commitAtMs,\n ]),\n ].sort((left, right) => left - right);\n\n for (const atMs of scheduleTimes) {\n timerHandles.push(\n this.scheduler.setTimeout(() => {\n if (finished || controller.signal.aborted) {\n return;\n }\n for (const item of groupedPlan.get(atMs) ?? []) startTrack(item);\n if (atMs === recipe.commitAtMs) commit();\n for (const item of plan) {\n if (\n item.track.atMs + item.track.durationMs === atMs &&\n !recipeEndTracks.has(item.track.id)\n ) {\n try {\n cleanupTrack(item.track.id);\n } catch (error) {\n fail('runtime_error', item.track.id, 'Primitive cleanup failed', error);\n }\n }\n }\n }, atMs),\n );\n }\n\n timerHandles.push(\n this.scheduler.setTimeout(() => {\n finalize('completed');\n }, recipe.durationMs),\n );\n }\n\n return {\n recipe,\n signal: controller.signal,\n done,\n abort: (reason?: string) => {\n requestAbort(reason ?? 'effect-recipe-aborted');\n },\n };\n }\n\n private resolveRecipe(\n recipeInput: EffectRecipeId | EffectRecipeDefinition,\n ): EffectRecipeDefinition {\n if (!isRecipeDefinition(recipeInput)) {\n const registration = this.recipeRegistry.get(recipeInput);\n if (!registration) {\n throw new EffectRecipeExecutorError(\n 'unknown_recipe',\n recipeInput,\n `\u672A\u6CE8\u518C\u7684 effect recipe: ${recipeInput}`,\n );\n }\n return registration.definition;\n }\n\n const validation = this.recipeRegistry.validate(recipeInput, 'custom');\n if (validation.entry) {\n return validation.entry.definition;\n }\n\n throw new EffectRecipeExecutorError(\n validation.errors.some((error) => error.code === 'unknown_primitive')\n ? 'unknown_primitive'\n : 'invalid_params',\n recipeInput.id,\n `Effect recipe \u5B9A\u4E49\u65E0\u6548: ${recipeInput.id}`,\n {\n trackId: resolveTrackIdFromValidationErrors(recipeInput, validation.errors),\n validationErrors: validation.errors,\n },\n );\n }\n\n private resolveTrackPlanItem(\n recipe: EffectRecipeDefinition,\n track: EffectRecipeTrackDefinition,\n runtimeContext: TRuntimeContext,\n ): EffectRecipeTrackPlanItem<TRuntimeContext> {\n const primitive = this.primitiveRegistry.get(track.primitiveId);\n if (!primitive) {\n throw new EffectRecipeExecutorError(\n 'unknown_primitive',\n recipe.id,\n `\u672A\u6CE8\u518C\u7684 effect primitive descriptor: ${track.primitiveId}`,\n {\n trackId: track.id,\n },\n );\n }\n\n const runtime = this.options.runtimeRegistry.get(track.primitiveId);\n if (!runtime) {\n throw new EffectRecipeExecutorError(\n 'unknown_runtime',\n recipe.id,\n `\u672A\u6CE8\u518C\u7684 effect primitive runtime: ${track.primitiveId}`,\n {\n trackId: track.id,\n },\n );\n }\n\n const resolvedParams: Record<string, ResolvedRecipeValue> = {};\n for (const [paramName, rawValue] of Object.entries(track.params)) {\n if (isEffectRecipeTuningPathReference(rawValue)) {\n const resolvedValue = this.resolveTuningReference(\n recipe,\n track,\n primitive,\n paramName,\n rawValue,\n runtimeContext,\n );\n resolvedParams[paramName] = resolvedValue;\n continue;\n }\n\n if (!isResolvedRecipeValue(rawValue)) {\n throw new EffectRecipeExecutorError(\n 'invalid_params',\n recipe.id,\n `Track \u53C2\u6570\u672A\u901A\u8FC7\u8FD0\u884C\u65F6\u503C\u6821\u9A8C: ${track.id}.${paramName}`,\n {\n trackId: track.id,\n },\n );\n }\n resolvedParams[paramName] = rawValue;\n }\n\n const validatedParams = validateResolvedEffectRecipeTrackParams(\n primitive,\n resolvedParams,\n `tracks.${track.id}.params`,\n );\n if (!validatedParams.params) {\n throw new EffectRecipeExecutorError(\n 'invalid_params',\n recipe.id,\n `Track \u53C2\u6570\u672A\u901A\u8FC7 descriptor \u6821\u9A8C: ${track.id}`,\n {\n trackId: track.id,\n validationErrors: validatedParams.errors,\n },\n );\n }\n\n return {\n track,\n primitive,\n runtime,\n params: validatedParams.params,\n executionContext: {\n recipeId: recipe.id,\n recipe,\n track,\n primitive,\n runtimeContext,\n },\n };\n }\n\n private resolveTuningReference(\n recipe: EffectRecipeDefinition,\n track: EffectRecipeTrackDefinition,\n primitive: EffectPrimitiveDescriptor,\n paramName: string,\n reference: EffectRecipeTuningPathReference,\n runtimeContext: TRuntimeContext,\n ): ResolvedRecipeValue {\n let resolvedValue: ResolvedRecipeValue;\n try {\n resolvedValue = this.options.resolveTuningPath(reference, {\n recipe,\n track,\n primitive,\n paramName,\n runtimeContext,\n });\n } catch (error) {\n throw new EffectRecipeExecutorError(\n 'tuning_resolution_failed',\n recipe.id,\n `tuningPath \u89E3\u6790\u5931\u8D25: ${reference.tuningPath}`,\n {\n trackId: track.id,\n cause: error,\n },\n );\n }\n\n if (!isResolvedRecipeValue(resolvedValue)) {\n throw new EffectRecipeExecutorError(\n 'tuning_resolution_failed',\n recipe.id,\n `tuningPath \u8FD4\u56DE\u4E86\u65E0\u6548\u503C: ${reference.tuningPath}`,\n {\n trackId: track.id,\n },\n );\n }\n\n return resolvedValue;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["isRecord", "hasOwn"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { RuntimeLogger } from '@bardway/trpg-media';
|
|
2
|
+
import type { EffectPrimitiveRegistry, EffectRecipeRegistry, ResolvedRecipeValue } from '../recipes.js';
|
|
3
|
+
import type { StoryCueEvent, StoryCuePlaybackControls, StoryContentSurface } from './StoryContentSurface.js';
|
|
4
|
+
import type { PixiLayoutRect } from '../PixiSessionLayout.js';
|
|
5
|
+
import type { BlurFilter, ColorMatrixFilter, Container, Filter, Graphics, Rectangle, Sprite, Text, Texture } from 'pixi.js';
|
|
6
|
+
import type { SessionAudioBus, SessionAudioCuePlayOptions } from '@bardway/trpg-media/audio';
|
|
7
|
+
import type { PixiAnimationDirector } from '../PixiAnimationDirector.js';
|
|
8
|
+
import type { PixiAnimationActivity } from '../PixiAnimationActivity.js';
|
|
9
|
+
import type { PixiSceneGraph } from '../PixiSceneGraph.js';
|
|
10
|
+
import type { PixiShaderRuntime } from '../PixiShaderRuntime.js';
|
|
11
|
+
import type { SessionTuningResolver } from '../tuning/SessionTuningResolver.js';
|
|
12
|
+
import { type EffectRecipeExecutorScheduler } from '../recipes/EffectRecipeExecutor.js';
|
|
13
|
+
import type { StoryTimelineClock } from './StoryTimelineClock.js';
|
|
14
|
+
interface Constructors {
|
|
15
|
+
Filter: typeof Filter;
|
|
16
|
+
BlurFilter: typeof BlurFilter;
|
|
17
|
+
ColorMatrixFilter: typeof ColorMatrixFilter;
|
|
18
|
+
Container: typeof Container;
|
|
19
|
+
Graphics: typeof Graphics;
|
|
20
|
+
Rectangle: typeof Rectangle;
|
|
21
|
+
Sprite: typeof Sprite;
|
|
22
|
+
Text: typeof Text;
|
|
23
|
+
Texture: typeof Texture;
|
|
24
|
+
}
|
|
25
|
+
export interface StoryPresentationAudioControls {
|
|
26
|
+
playCue(id: string, options?: SessionAudioCuePlayOptions): boolean;
|
|
27
|
+
duck(bus: SessionAudioBus, amount: number): () => void;
|
|
28
|
+
setDuck?(id: string, bus: SessionAudioBus, amount: number, rampMs: number): void;
|
|
29
|
+
clearDuck?(id: string): void;
|
|
30
|
+
}
|
|
31
|
+
export interface StoryPresentationError {
|
|
32
|
+
recipeId: string;
|
|
33
|
+
trackId?: string;
|
|
34
|
+
primitiveId?: string;
|
|
35
|
+
reason: string;
|
|
36
|
+
}
|
|
37
|
+
export interface PixiStoryPresentationEngineOptions<TContent> {
|
|
38
|
+
scene: PixiSceneGraph;
|
|
39
|
+
story: StoryContentSurface<TContent>;
|
|
40
|
+
logger: RuntimeLogger;
|
|
41
|
+
primitiveRegistry: EffectPrimitiveRegistry;
|
|
42
|
+
recipeRegistry: EffectRecipeRegistry;
|
|
43
|
+
tuningDefaults: Readonly<Record<string, ResolvedRecipeValue>>;
|
|
44
|
+
mediaBounds: PixiLayoutRect;
|
|
45
|
+
particleColors: {
|
|
46
|
+
ash: string;
|
|
47
|
+
dust: string;
|
|
48
|
+
};
|
|
49
|
+
resolveAudioCueId: (id: string) => string | null;
|
|
50
|
+
audioBuses: readonly string[];
|
|
51
|
+
directRecipeId?: string;
|
|
52
|
+
directCueId?: string;
|
|
53
|
+
constructors: Constructors;
|
|
54
|
+
animation: PixiAnimationDirector;
|
|
55
|
+
shaderRuntime: PixiShaderRuntime;
|
|
56
|
+
getAudio: () => StoryPresentationAudioControls | null;
|
|
57
|
+
getTuning: () => SessionTuningResolver | undefined;
|
|
58
|
+
requestRender: () => void;
|
|
59
|
+
generateTexture?: (shape: Graphics) => Texture;
|
|
60
|
+
scheduler?: EffectRecipeExecutorScheduler;
|
|
61
|
+
clock?: StoryTimelineClock;
|
|
62
|
+
activity?: PixiAnimationActivity;
|
|
63
|
+
onError?: (error: StoryPresentationError) => void;
|
|
64
|
+
}
|
|
65
|
+
export declare const resolveStoryContentAlpha: (elapsedMs: number, durationMs: number, from: number, to: number, holdMs?: number) => number;
|
|
66
|
+
export declare const CONSUMED_PARAMS: Readonly<Record<string, readonly string[]>>;
|
|
67
|
+
export declare class PixiStoryPresentationEngine<TContent> {
|
|
68
|
+
private readonly options;
|
|
69
|
+
private readonly runtimeRegistry;
|
|
70
|
+
private readonly executor;
|
|
71
|
+
private readonly runs;
|
|
72
|
+
private reducedMotion;
|
|
73
|
+
private destroyed;
|
|
74
|
+
constructor(options: PixiStoryPresentationEngineOptions<TContent>);
|
|
75
|
+
getRegisteredPrimitiveIds(): readonly string[];
|
|
76
|
+
applyState(): void;
|
|
77
|
+
playCue(cue: StoryCueEvent<TContent>, controls: StoryCuePlaybackControls): void;
|
|
78
|
+
private play;
|
|
79
|
+
setReducedMotion(value: boolean): void;
|
|
80
|
+
abort(reason?: string, eventIds?: readonly string[]): void;
|
|
81
|
+
reset(): void;
|
|
82
|
+
destroy(): void;
|
|
83
|
+
private roots;
|
|
84
|
+
private animate;
|
|
85
|
+
private executePrimitive;
|
|
86
|
+
private readonly particleTextures;
|
|
87
|
+
private particleTexture;
|
|
88
|
+
private particles;
|
|
89
|
+
}
|
|
90
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Container, Sprite } from 'pixi.js';
|
|
2
|
+
import type { PixiLayoutRect } from '../PixiSessionLayout.js';
|
|
3
|
+
export interface StoryCueEvent<TContent> {
|
|
4
|
+
eventId: string;
|
|
5
|
+
recipeId: string;
|
|
6
|
+
content: TContent;
|
|
7
|
+
}
|
|
8
|
+
export interface StoryCuePlaybackControls {
|
|
9
|
+
ready?(): void;
|
|
10
|
+
readonly signal: AbortSignal;
|
|
11
|
+
commit(): void;
|
|
12
|
+
done(outcome?: 'failed'): void;
|
|
13
|
+
}
|
|
14
|
+
export interface PreparedStoryContentTransition {
|
|
15
|
+
readonly outgoing: Container | null;
|
|
16
|
+
readonly incoming: Container;
|
|
17
|
+
readonly incomingImage: Sprite;
|
|
18
|
+
readonly incomingRect: PixiLayoutRect;
|
|
19
|
+
readonly effectOverlayRoot?: Container;
|
|
20
|
+
setTopLayerActive(active: boolean): void;
|
|
21
|
+
playDefaultEntrance(signal: AbortSignal): Promise<boolean>;
|
|
22
|
+
commit(): void;
|
|
23
|
+
finish(): void | Promise<void>;
|
|
24
|
+
cancel(): void;
|
|
25
|
+
}
|
|
26
|
+
export interface StoryContentSurface<TContent> {
|
|
27
|
+
prepareContentTransition(content: TContent, signal: AbortSignal): Promise<PreparedStoryContentTransition | null>;
|
|
28
|
+
getRenderedImageRect(): PixiLayoutRect | null;
|
|
29
|
+
getPresentationTargets(): {
|
|
30
|
+
currentContent?: Container | null;
|
|
31
|
+
readonly contentRoot: Container;
|
|
32
|
+
readonly overlayRoot: Container;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Filter } from 'pixi.js';
|
|
2
|
+
export type StoryRevealStyle = 'highlights-first' | 'random-fragments';
|
|
3
|
+
/** Retained single-pass vignette filter; only uniforms change during playback. */
|
|
4
|
+
export declare function createStoryVignetteFilter(FilterConstructor: typeof Filter): {
|
|
5
|
+
filter: Filter;
|
|
6
|
+
vignette: Float32Array<ArrayBuffer>;
|
|
7
|
+
ellipse: Float32Array<ArrayBuffer>;
|
|
8
|
+
};
|
|
9
|
+
/** Retained single-pass reveal filter for luminance dissolve and stable Voronoi fragments. */
|
|
10
|
+
export declare function createStoryRevealFilter(style: StoryRevealStyle, FilterConstructor: typeof Filter): {
|
|
11
|
+
filter: Filter;
|
|
12
|
+
reveal: Float32Array<ArrayBuffer>;
|
|
13
|
+
detail: Float32Array<ArrayBuffer>;
|
|
14
|
+
fadeRatios: Float32Array<ArrayBuffer>;
|
|
15
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Logical animation time. Only the renderer's ticker advances production clocks. */
|
|
2
|
+
export declare class StoryTimelineClock {
|
|
3
|
+
private time;
|
|
4
|
+
private serial;
|
|
5
|
+
private paused;
|
|
6
|
+
private rate;
|
|
7
|
+
private readonly timers;
|
|
8
|
+
private readonly listeners;
|
|
9
|
+
now(): number;
|
|
10
|
+
resourceCounts(): {
|
|
11
|
+
timers: number;
|
|
12
|
+
samplers: number;
|
|
13
|
+
};
|
|
14
|
+
setPaused(value: boolean): void;
|
|
15
|
+
setPlaybackRate(value: number): void;
|
|
16
|
+
subscribe(listener: (nowMs: number) => void): () => void;
|
|
17
|
+
setTimeout(callback: () => void, delayMs: number): number;
|
|
18
|
+
clearTimeout(handle: unknown): void;
|
|
19
|
+
advance(deltaMs: number): void;
|
|
20
|
+
clear(): void;
|
|
21
|
+
private sample;
|
|
22
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const clamp01: (value: number) => number;
|
|
2
|
+
export declare const smooth: (value: number) => number;
|
|
3
|
+
export declare function envelope(time: number, attack: number, hold: number, release: number): number;
|
|
4
|
+
export declare function seededRandom(seed: number): () => number;
|
|
5
|
+
export declare function storySeed(value: string): number;
|
|
6
|
+
export declare function shakeSample(time: number, duration: number, frequency: number, decay: number, seed: number): number;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@bardway/trpg-media/tuning';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@bardway/trpg-media/tuning';
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Container, Graphics, Text } from 'pixi.js';
|
|
2
|
+
import type { PixiStageTheme } from '../PixiStageTheme.js';
|
|
3
|
+
import type { createPixiTypography, PixiTypographyToken } from '../PixiTypography.js';
|
|
4
|
+
export interface PixiStageUiConstructors {
|
|
5
|
+
Container: new () => Container;
|
|
6
|
+
Graphics: new () => Graphics;
|
|
7
|
+
Text: new (options: import('pixi.js').TextOptions) => Text;
|
|
8
|
+
}
|
|
9
|
+
export interface PixiStageButtonOptions {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
label: string;
|
|
15
|
+
enabled: boolean;
|
|
16
|
+
onActivate: () => void;
|
|
17
|
+
typography?: PixiTypographyToken;
|
|
18
|
+
accessibleLabel: string;
|
|
19
|
+
}
|
|
20
|
+
/** A retained, pointer-safe canvas button. Consumers update props rather than recreate listeners. */
|
|
21
|
+
export declare class PixiStageButton {
|
|
22
|
+
private readonly pixiStageTheme;
|
|
23
|
+
private readonly pixiTypography;
|
|
24
|
+
readonly node: Container;
|
|
25
|
+
private readonly background;
|
|
26
|
+
private readonly label;
|
|
27
|
+
private options;
|
|
28
|
+
private pressed;
|
|
29
|
+
constructor(constructors: PixiStageUiConstructors, options: PixiStageButtonOptions, pixiStageTheme: PixiStageTheme, pixiTypography: ReturnType<typeof createPixiTypography>);
|
|
30
|
+
update(options: PixiStageButtonOptions): void;
|
|
31
|
+
activate(): void;
|
|
32
|
+
private setHovered;
|
|
33
|
+
private setPressed;
|
|
34
|
+
private redraw;
|
|
35
|
+
}
|
|
36
|
+
export declare const createPixiStageLabel: (constructors: Pick<PixiStageUiConstructors, "Text">, text: string, typography: PixiTypographyToken, pixiTypography: ReturnType<typeof createPixiTypography>) => Text;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function assertUniformFields<N extends string, A extends string>(value: unknown, numbers: readonly N[], arrays: readonly A[]): asserts value is Record<N, number> & Record<A, Float32Array>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,46 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bardway/trpg-pixi",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"description": "
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Extracted reusable pixi runtime for TRPG hosts",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"NOTICE.md",
|
|
10
|
+
"LICENSE",
|
|
11
|
+
"NOTICE"
|
|
12
|
+
],
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/bardway/mingriAgency_TRPGEngine.git"
|
|
16
|
+
},
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"registry": "https://registry.npmjs.org/",
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"import": "./dist/index.js"
|
|
25
|
+
},
|
|
26
|
+
"./recipes": {
|
|
27
|
+
"types": "./dist/recipes.d.ts",
|
|
28
|
+
"import": "./dist/recipes.js"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"gsap": "3.15.0",
|
|
34
|
+
"@bardway/trpg-media": "0.1.0",
|
|
35
|
+
"@bardway/trpg-display": "0.1.0"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"pixi.js": "8.19.0"
|
|
39
|
+
},
|
|
40
|
+
"trpg": {
|
|
41
|
+
"entries": {
|
|
42
|
+
"index": "src/index.ts",
|
|
43
|
+
"recipes": "src/recipes.ts"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|