@zhin.js/plugin-rps 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -0
- package/commands/rps/[action:string=].ts +15 -0
- package/lib/engine.d.ts +0 -1
- package/lib/engine.js +2 -1
- package/lib/engine.js.map +1 -1
- package/lib/game-flow.d.ts +6 -7
- package/lib/game-flow.js +18 -16
- package/lib/game-flow.js.map +1 -1
- package/lib/index.d.ts +8 -2
- package/lib/index.js +8 -25
- package/lib/index.js.map +1 -1
- package/lib/memory-db.d.ts +6 -0
- package/lib/memory-db.js +18 -0
- package/lib/memory-db.js.map +1 -0
- package/lib/models.d.ts +5 -4
- package/lib/models.js +2 -2
- package/lib/models.js.map +1 -1
- package/lib/rps-command.d.ts +4 -3
- package/lib/rps-command.js +5 -1
- package/lib/rps-command.js.map +1 -1
- package/lib/runtime-store.d.ts +6 -0
- package/lib/runtime-store.js +7 -0
- package/lib/runtime-store.js.map +1 -0
- package/lib/session-service.d.ts +1 -3
- package/lib/session-service.js +3 -12
- package/lib/session-service.js.map +1 -1
- package/lib/view.d.ts +2 -3
- package/lib/view.js +5 -3
- package/lib/view.js.map +1 -1
- package/middlewares/rps-alias.ts +18 -0
- package/middlewares/rps-choice.ts +66 -0
- package/package.json +45 -10
- package/plugin.ts +63 -0
- package/schema.json +6 -0
- package/src/engine.ts +3 -1
- package/src/game-flow.ts +21 -22
- package/src/index.ts +9 -36
- package/src/memory-db.ts +22 -0
- package/src/models.ts +7 -4
- package/src/rps-command.ts +12 -3
- package/src/runtime-store.ts +9 -0
- package/src/session-service.ts +4 -11
- package/src/view.ts +6 -3
- package/lib/commands.d.ts +0 -6
- package/lib/commands.d.ts.map +0 -1
- package/lib/commands.js +0 -86
- package/lib/commands.js.map +0 -1
- package/lib/engine.d.ts.map +0 -1
- package/lib/game-flow.d.ts.map +0 -1
- package/lib/hub-register.d.ts +0 -5
- package/lib/hub-register.d.ts.map +0 -1
- package/lib/hub-register.js +0 -26
- package/lib/hub-register.js.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/models.d.ts.map +0 -1
- package/lib/rps-command.d.ts.map +0 -1
- package/lib/session-service.d.ts.map +0 -1
- package/lib/view.d.ts.map +0 -1
- package/plugin.yml +0 -2
- package/src/commands.ts +0 -102
- package/src/hub-register.ts +0 -30
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/plugin-rps",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Zhin.js 猜拳游戏 — 石头剪刀布三局两胜",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "Zhin.js 猜拳游戏 — 石头剪刀布三局两胜 (Plugin Runtime)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
7
7
|
"types": "./lib/index.d.ts",
|
|
@@ -14,24 +14,59 @@
|
|
|
14
14
|
"./package.json": "./package.json"
|
|
15
15
|
},
|
|
16
16
|
"files": [
|
|
17
|
+
"plugin.ts",
|
|
18
|
+
"schema.json",
|
|
19
|
+
"commands",
|
|
20
|
+
"middlewares",
|
|
17
21
|
"src",
|
|
18
22
|
"lib",
|
|
19
|
-
"plugin.yml",
|
|
20
23
|
"README.md"
|
|
21
24
|
],
|
|
22
25
|
"license": "MIT",
|
|
23
|
-
"peerDependencies": {
|
|
24
|
-
"zhin.js": "4.1.0"
|
|
25
|
-
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@zhin.js/
|
|
27
|
+
"@zhin.js/command": "1.0.1",
|
|
28
|
+
"@zhin.js/core": "1.3.5",
|
|
29
|
+
"@zhin.js/game-kit": "1.0.2",
|
|
30
|
+
"@zhin.js/middleware": "1.0.1",
|
|
31
|
+
"@zhin.js/plugin-runtime": "1.0.1"
|
|
28
32
|
},
|
|
29
33
|
"devDependencies": {
|
|
30
34
|
"typescript": "^6.0.3",
|
|
31
|
-
"
|
|
35
|
+
"vitest": "^4.1.10"
|
|
36
|
+
},
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/zhinjs/zhin.git",
|
|
40
|
+
"directory": "plugins/games/rps"
|
|
41
|
+
},
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public",
|
|
44
|
+
"registry": "https://registry.npmjs.org"
|
|
45
|
+
},
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": "^20.19.0 || >=22.12.0"
|
|
48
|
+
},
|
|
49
|
+
"zhin": {
|
|
50
|
+
"protocol": 1,
|
|
51
|
+
"type": "plugin",
|
|
52
|
+
"entry": "./plugin.ts",
|
|
53
|
+
"engine": "^1.0.0",
|
|
54
|
+
"runtime": "trusted",
|
|
55
|
+
"features": [
|
|
56
|
+
{
|
|
57
|
+
"package": "@zhin.js/command",
|
|
58
|
+
"api": "^1.0.0"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"package": "@zhin.js/middleware",
|
|
62
|
+
"api": "^1.0.0"
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
"plugins": []
|
|
32
66
|
},
|
|
33
67
|
"scripts": {
|
|
34
|
-
"build": "tsc
|
|
35
|
-
"clean": "rimraf lib"
|
|
68
|
+
"build": "tsc",
|
|
69
|
+
"clean": "rimraf lib",
|
|
70
|
+
"test": "NODE_OPTIONS=--experimental-strip-types vitest run --root ../../.. plugins/games/rps/tests"
|
|
36
71
|
}
|
|
37
72
|
}
|
package/plugin.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { definePlugin, databaseHostToken, scheduleHostToken } from '@zhin.js/plugin-runtime';
|
|
2
|
+
import {
|
|
3
|
+
registerRuntimeGame,
|
|
4
|
+
initGameRecordHost,
|
|
5
|
+
DEFAULT_GAME_STALE_CRON,
|
|
6
|
+
DEFAULT_GAME_STALE_IDLE_MS,
|
|
7
|
+
} from '@zhin.js/game-kit';
|
|
8
|
+
import { mountRpsHostServices, mountRpsMemoryServices } from './src/memory-db.js';
|
|
9
|
+
import { gameServicesToken } from './src/runtime-store.js';
|
|
10
|
+
import type { SessionService } from './src/session-service.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Plugin Runtime:
|
|
14
|
+
* - Commands under `commands/` are authoritative (help + start/continue/quit via in-memory DB).
|
|
15
|
+
* - DB: prefer databaseHostToken; else in-memory SessionService.
|
|
16
|
+
* - Choice middleware under `middlewares/` handles RPS choice payloads (Sandbox action→text).
|
|
17
|
+
*/
|
|
18
|
+
export default definePlugin({
|
|
19
|
+
name: 'rps',
|
|
20
|
+
metadata: {
|
|
21
|
+
displayName: 'RPS',
|
|
22
|
+
},
|
|
23
|
+
setup(context) {
|
|
24
|
+
let services: SessionService;
|
|
25
|
+
if (context.resources.has(databaseHostToken)) {
|
|
26
|
+
const host = context.resources.use(databaseHostToken);
|
|
27
|
+
services = mountRpsHostServices(host);
|
|
28
|
+
context.lifecycle.add(initGameRecordHost(host));
|
|
29
|
+
} else {
|
|
30
|
+
services = mountRpsMemoryServices();
|
|
31
|
+
}
|
|
32
|
+
context.resources.provide(gameServicesToken, services);
|
|
33
|
+
const disposeHub = registerRuntimeGame({
|
|
34
|
+
id: 'rps',
|
|
35
|
+
title: '猜拳对决',
|
|
36
|
+
icon: '✊',
|
|
37
|
+
description: '石头剪刀布,三局两胜',
|
|
38
|
+
commandPrefix: '/猜拳',
|
|
39
|
+
quickStart: '开始',
|
|
40
|
+
aliases: ['rps'],
|
|
41
|
+
menus: [
|
|
42
|
+
{ id: 'start', label: '🎮 开始对局' },
|
|
43
|
+
{ id: 'continue', label: '🔄 继续' },
|
|
44
|
+
{ id: 'help', label: '📖 玩法说明' },
|
|
45
|
+
],
|
|
46
|
+
});
|
|
47
|
+
context.lifecycle.add(disposeHub);
|
|
48
|
+
|
|
49
|
+
if (context.resources.has(scheduleHostToken)) {
|
|
50
|
+
const schedule = context.resources.use(scheduleHostToken);
|
|
51
|
+
const disposeCron = schedule.register({
|
|
52
|
+
id: 'rps/abort-stale',
|
|
53
|
+
cron: DEFAULT_GAME_STALE_CRON,
|
|
54
|
+
description: 'Abort stale rps sessions',
|
|
55
|
+
async execute() {
|
|
56
|
+
if (!services.abortStale) return;
|
|
57
|
+
await services.abortStale(DEFAULT_GAME_STALE_IDLE_MS);
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
context.lifecycle.add(disposeCron);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
});
|
package/schema.json
ADDED
package/src/engine.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { secureRandomItem } from '@zhin.js/game-kit';
|
|
2
|
+
|
|
1
3
|
export const RPS_PREFIX = 'rps';
|
|
2
4
|
|
|
3
5
|
export type RpsMove = 'rock' | 'paper' | 'scissors';
|
|
@@ -16,7 +18,7 @@ const BEATS: Record<RpsMove, RpsMove> = {
|
|
|
16
18
|
|
|
17
19
|
export function randomBotMove(): RpsMove {
|
|
18
20
|
const moves: RpsMove[] = ['rock', 'paper', 'scissors'];
|
|
19
|
-
return
|
|
21
|
+
return secureRandomItem(moves);
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
/** 1=玩家胜 2=机器人胜 0=平局 */
|
package/src/game-flow.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { Adapter, Message, Plugin } from 'zhin.js';
|
|
1
|
+
import type { Adapter, Message, Plugin } from '@zhin.js/core';
|
|
2
|
+
import { plainTextFromSendContent, recordGameOutcome } from '@zhin.js/game-kit';
|
|
2
3
|
import type { RpsSessionRow } from './models.js';
|
|
3
4
|
import {
|
|
4
5
|
RPS_PREFIX,
|
|
@@ -11,13 +12,15 @@ import type { SessionService } from './session-service.js';
|
|
|
11
12
|
import { buildRpsView } from './view.js';
|
|
12
13
|
|
|
13
14
|
export async function sendOrEditView(
|
|
14
|
-
plugin: Plugin,
|
|
15
|
+
plugin: Plugin | null,
|
|
15
16
|
services: SessionService,
|
|
16
17
|
message: Message<any>,
|
|
17
18
|
session: RpsSessionRow,
|
|
18
19
|
lastRound?: { player: RpsMove; bot: RpsMove; result: 0 | 1 | 2 },
|
|
19
|
-
): Promise<void> {
|
|
20
|
-
const content = buildRpsView(session, lastRound);
|
|
20
|
+
): Promise<string | void> {
|
|
21
|
+
const content = buildRpsView(session, lastRound, message.$channel.type);
|
|
22
|
+
if (!plugin) return plainTextFromSendContent(content);
|
|
23
|
+
|
|
21
24
|
const adapter = plugin.root.inject(message.$adapter) as Adapter;
|
|
22
25
|
|
|
23
26
|
if (session.board_message_id) {
|
|
@@ -40,7 +43,7 @@ export async function sendOrEditView(
|
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
export async function startGame(
|
|
43
|
-
plugin: Plugin,
|
|
46
|
+
plugin: Plugin | null,
|
|
44
47
|
services: SessionService,
|
|
45
48
|
message: Message<any>,
|
|
46
49
|
): Promise<string | undefined> {
|
|
@@ -53,12 +56,12 @@ export async function startGame(
|
|
|
53
56
|
return `本频道 ${active.player_name} 正在猜拳对决中。`;
|
|
54
57
|
}
|
|
55
58
|
const session = await services.createSession(message);
|
|
56
|
-
await sendOrEditView(plugin, services, message, session);
|
|
57
|
-
return undefined;
|
|
59
|
+
const text = await sendOrEditView(plugin, services, message, session);
|
|
60
|
+
return typeof text === 'string' ? text : undefined;
|
|
58
61
|
}
|
|
59
62
|
|
|
60
63
|
export async function handleChoice(
|
|
61
|
-
plugin: Plugin,
|
|
64
|
+
plugin: Plugin | null,
|
|
62
65
|
services: SessionService,
|
|
63
66
|
message: Message<any>,
|
|
64
67
|
sessionId: string,
|
|
@@ -72,16 +75,9 @@ export async function handleChoice(
|
|
|
72
75
|
if (session.player_id !== message.$sender.id) return '这是别人的对局。';
|
|
73
76
|
|
|
74
77
|
if (choiceId === 'restart') {
|
|
75
|
-
await services.updateSession(session.id, {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
round: 0,
|
|
79
|
-
status: 'active',
|
|
80
|
-
board_message_id: '',
|
|
81
|
-
});
|
|
82
|
-
const updated = (await services.getById(session.id))!;
|
|
83
|
-
await sendOrEditView(plugin, services, message, updated);
|
|
84
|
-
return null;
|
|
78
|
+
await services.updateSession(session.id, { status: 'aborted' });
|
|
79
|
+
// text-only 模式(plugin===null)下 startGame 的唯一输出就是返回文本
|
|
80
|
+
return (await startGame(plugin, services, message)) ?? null;
|
|
85
81
|
}
|
|
86
82
|
|
|
87
83
|
const player = choiceId as RpsMove;
|
|
@@ -106,12 +102,14 @@ export async function handleChoice(
|
|
|
106
102
|
});
|
|
107
103
|
|
|
108
104
|
const updated = (await services.getById(session.id))!;
|
|
109
|
-
|
|
110
|
-
|
|
105
|
+
if (status === 'won') void recordGameOutcome(message, 'rps', 'won', playerWins * 10);
|
|
106
|
+
else if (status === 'lost') void recordGameOutcome(message, 'rps', 'lost');
|
|
107
|
+
const text = await sendOrEditView(plugin, services, message, updated, { player, bot, result });
|
|
108
|
+
return typeof text === 'string' ? text : null;
|
|
111
109
|
}
|
|
112
110
|
|
|
113
111
|
export async function continueGame(
|
|
114
|
-
plugin: Plugin,
|
|
112
|
+
plugin: Plugin | null,
|
|
115
113
|
services: SessionService,
|
|
116
114
|
message: Message<any>,
|
|
117
115
|
): Promise<string> {
|
|
@@ -120,7 +118,8 @@ export async function continueGame(
|
|
|
120
118
|
message.$sender.id,
|
|
121
119
|
);
|
|
122
120
|
if (!session) return '你没有进行中的猜拳,发送「猜拳 开始」。';
|
|
123
|
-
await sendOrEditView(plugin, services, message, session);
|
|
121
|
+
const text = await sendOrEditView(plugin, services, message, session);
|
|
122
|
+
if (typeof text === 'string') return text;
|
|
124
123
|
return '已刷新猜拳界面。';
|
|
125
124
|
}
|
|
126
125
|
|
package/src/index.ts
CHANGED
|
@@ -1,36 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const plugin = usePlugin();
|
|
12
|
-
const { logger, useContext, addCron } = plugin;
|
|
13
|
-
|
|
14
|
-
registerModels(plugin);
|
|
15
|
-
|
|
16
|
-
let services: SessionService | null = null;
|
|
17
|
-
|
|
18
|
-
useContext('database', (dbFeature: DatabaseFeature) => {
|
|
19
|
-
services = createServices(resolveGameDatabase(dbFeature));
|
|
20
|
-
logger.info(formatCompact({ 模块: '猜拳', 数据模型: '已就绪' }));
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
registerRpsHub(() => services);
|
|
24
|
-
registerCommands(plugin, () => services);
|
|
25
|
-
registerInteractive(plugin, () => services);
|
|
26
|
-
registerTextFallback(plugin, () => services);
|
|
27
|
-
|
|
28
|
-
addCron(
|
|
29
|
-
new Cron('0 */15 * * * *', async () => {
|
|
30
|
-
if (!services) return;
|
|
31
|
-
const n = await services.abortStale(30 * 60 * 1000);
|
|
32
|
-
if (n > 0) logger.debug(formatCompact({ 猜拳: '清理超时局', count: n }));
|
|
33
|
-
}),
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
logger.info(formatCompact({ 模块: '猜拳', 状态: '已加载' }));
|
|
1
|
+
export { RPS_HELP } from './rps-command.js';
|
|
2
|
+
export { gameServicesToken, resolveGameServices } from './runtime-store.js';
|
|
3
|
+
export { createInMemoryRpsDb, mountRpsMemoryServices } from './memory-db.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 已由 plugin.ts 接线:commands/ 命令、middlewares/ 文本与选项中间件、
|
|
7
|
+
* 游戏大厅注册(registerRuntimeGame)、过期会话 cron(scheduleHostToken)、
|
|
8
|
+
* host DatabaseHost(databaseHostToken)。仍未接:interactive 按钮回调。
|
|
9
|
+
*/
|
package/src/memory-db.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createHostGameDb, createInMemoryGameDb } from '@zhin.js/game-kit';
|
|
2
|
+
import type { DatabaseHost } from '@zhin.js/plugin-runtime';
|
|
3
|
+
import { defineHostTables } from './models.js';
|
|
4
|
+
import { createServices, type RpsDatabase, type SessionService } from './session-service.js';
|
|
5
|
+
|
|
6
|
+
const RPS_TABLES = ['rps_sessions'] as const;
|
|
7
|
+
|
|
8
|
+
/** In-memory rps_sessions for Plugin Runtime slice-2 (no DatabaseFeature). */
|
|
9
|
+
export function createInMemoryRpsDb(): RpsDatabase {
|
|
10
|
+
return createInMemoryGameDb(RPS_TABLES) as unknown as RpsDatabase;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function mountRpsMemoryServices(): SessionService {
|
|
14
|
+
const services = createServices(createInMemoryRpsDb());
|
|
15
|
+
return services;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function mountRpsHostServices(host: DatabaseHost): SessionService {
|
|
19
|
+
defineHostTables(host);
|
|
20
|
+
const services = createServices(createHostGameDb(host, RPS_TABLES) as unknown as RpsDatabase);
|
|
21
|
+
return services;
|
|
22
|
+
}
|
package/src/models.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { Models
|
|
1
|
+
import type { Models } from '@zhin.js/core';
|
|
2
2
|
|
|
3
3
|
export type RpsSessionStatus = 'active' | 'won' | 'lost' | 'aborted';
|
|
4
4
|
|
|
5
|
-
declare module 'zhin.js' {
|
|
5
|
+
declare module '@zhin.js/core' {
|
|
6
6
|
interface Models {
|
|
7
7
|
rps_sessions: {
|
|
8
8
|
id: string;
|
|
@@ -26,8 +26,11 @@ declare module 'zhin.js' {
|
|
|
26
26
|
|
|
27
27
|
export type RpsSessionRow = Models['rps_sessions'];
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
|
|
30
|
+
export function defineHostTables(
|
|
31
|
+
db: { define: (name: string, definition: Record<string, unknown>) => void },
|
|
32
|
+
): void {
|
|
33
|
+
db.define('rps_sessions', {
|
|
31
34
|
id: { type: 'text', primary: true },
|
|
32
35
|
adapter: { type: 'text', nullable: false },
|
|
33
36
|
endpoint: { type: 'text', nullable: false },
|
package/src/rps-command.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Message, Plugin } from 'zhin.js';
|
|
2
|
-
import { channelKey } from '@zhin.js/game-
|
|
1
|
+
import type { Message, Plugin } from '@zhin.js/core';
|
|
2
|
+
import { channelKey } from '@zhin.js/game-kit';
|
|
3
3
|
import { continueGame, startGame } from './game-flow.js';
|
|
4
4
|
import type { SessionService } from './session-service.js';
|
|
5
5
|
|
|
@@ -12,7 +12,7 @@ export const RPS_HELP = [
|
|
|
12
12
|
].join('\n');
|
|
13
13
|
|
|
14
14
|
export async function runRpsCommand(
|
|
15
|
-
plugin: Plugin,
|
|
15
|
+
plugin: Plugin | null,
|
|
16
16
|
services: SessionService,
|
|
17
17
|
message: Message<any>,
|
|
18
18
|
action: string,
|
|
@@ -43,3 +43,12 @@ export async function runRpsCommand(
|
|
|
43
43
|
|
|
44
44
|
return `未知子命令:${action}\n\n${RPS_HELP}`;
|
|
45
45
|
}
|
|
46
|
+
|
|
47
|
+
/** Plugin Runtime / smoke: text-only, no Adapter.editMessage. */
|
|
48
|
+
export async function runRpsCommandText(
|
|
49
|
+
services: SessionService,
|
|
50
|
+
message: Message<any>,
|
|
51
|
+
action: string,
|
|
52
|
+
): Promise<string> {
|
|
53
|
+
return (await runRpsCommand(null, services, message, action)) ?? '';
|
|
54
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createToken } from '@zhin.js/plugin-runtime';
|
|
2
|
+
import type { SessionService } from './session-service.js';
|
|
3
|
+
|
|
4
|
+
/** Owner-scoped service consumed by discovered commands and middleware. */
|
|
5
|
+
export const gameServicesToken = createToken<SessionService>('zhin.game.rps.services');
|
|
6
|
+
|
|
7
|
+
export function resolveGameServices(context: { use<T>(token: typeof gameServicesToken): T }): SessionService {
|
|
8
|
+
return context.use(gameServicesToken) as SessionService;
|
|
9
|
+
}
|
package/src/session-service.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Database,
|
|
2
|
-
import { channelKey, generateSessionId } from '@zhin.js/game-
|
|
1
|
+
import type { Database, Message, Models, RelatedModel } from '@zhin.js/core';
|
|
2
|
+
import { channelKey, generateSessionId, boardMessageMatches } from '@zhin.js/game-kit';
|
|
3
3
|
import type { RpsSessionRow } from './models.js';
|
|
4
4
|
|
|
5
5
|
export type RpsDatabase = Database<unknown, Models, string>;
|
|
@@ -30,13 +30,9 @@ export class SessionService {
|
|
|
30
30
|
|
|
31
31
|
async getActiveByBoardMessageId(messageId: string): Promise<RpsSessionRow | null> {
|
|
32
32
|
if (!messageId) return null;
|
|
33
|
-
const rows = await getModel(this.db).findAll({
|
|
33
|
+
const rows = await getModel(this.db).findAll({});
|
|
34
34
|
for (const row of rows) {
|
|
35
|
-
|
|
36
|
-
if (!stored) continue;
|
|
37
|
-
if (stored === messageId || stored.endsWith(`:${messageId}`)) return row;
|
|
38
|
-
const tail = stored.split(':').pop();
|
|
39
|
-
if (tail && messageId.endsWith(tail)) return row;
|
|
35
|
+
if (boardMessageMatches(row.board_message_id ?? '', messageId)) return row;
|
|
40
36
|
}
|
|
41
37
|
return null;
|
|
42
38
|
}
|
|
@@ -87,6 +83,3 @@ export function createServices(db: RpsDatabase): SessionService {
|
|
|
87
83
|
return new SessionService(db);
|
|
88
84
|
}
|
|
89
85
|
|
|
90
|
-
export function resolveGameDatabase(feature: DatabaseFeature): RpsDatabase {
|
|
91
|
-
return feature.db;
|
|
92
|
-
}
|
package/src/view.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { buildChoiceKeyboard } from '@zhin.js/game-
|
|
2
|
-
import type { SendContent } from 'zhin.js';
|
|
1
|
+
import { buildChoiceKeyboard } from '@zhin.js/game-kit';
|
|
2
|
+
import type { SendContent } from '@zhin.js/core';
|
|
3
3
|
import type { RpsSessionRow } from './models.js';
|
|
4
4
|
import { MOVE_LABELS, RPS_PREFIX, WIN_TARGET, type RpsMove } from './engine.js';
|
|
5
5
|
|
|
6
6
|
export function buildRpsView(
|
|
7
7
|
session: RpsSessionRow,
|
|
8
8
|
lastRound?: { player: RpsMove; bot: RpsMove; result: 0 | 1 | 2 },
|
|
9
|
+
channelType?: string,
|
|
9
10
|
): SendContent {
|
|
10
11
|
const terminal = session.status !== 'active';
|
|
11
12
|
const lines = [
|
|
@@ -37,7 +38,7 @@ export function buildRpsView(
|
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
const choices = terminal
|
|
40
|
-
? [{ id: 'restart', label: '🔄 再来一局', style: 'primary' as const }]
|
|
41
|
+
? [{ id: 'restart', label: '🔄 再来一局', style: 'primary' as const, keepEnabledWhenTerminal: true }]
|
|
41
42
|
: (['rock', 'paper', 'scissors'] as RpsMove[]).map((m) => ({
|
|
42
43
|
id: m,
|
|
43
44
|
label: MOVE_LABELS[m],
|
|
@@ -52,5 +53,7 @@ export function buildRpsView(
|
|
|
52
53
|
terminal,
|
|
53
54
|
buttonsPerRow: 3,
|
|
54
55
|
fallbackHint: '回复数字出拳(1石头 2布 3剪刀)',
|
|
56
|
+
interactionProfile: terminal ? 'terminal' : 'gameplay',
|
|
57
|
+
channelType,
|
|
55
58
|
});
|
|
56
59
|
}
|
package/lib/commands.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { type Plugin } from 'zhin.js';
|
|
2
|
-
import type { SessionService } from './session-service.js';
|
|
3
|
-
export declare function registerCommands(plugin: Plugin, getServices: () => SessionService | null): void;
|
|
4
|
-
export declare function registerInteractive(plugin: Plugin, getServices: () => SessionService | null): void;
|
|
5
|
-
export declare function registerTextFallback(plugin: Plugin, getServices: () => SessionService | null): void;
|
|
6
|
-
//# sourceMappingURL=commands.d.ts.map
|
package/lib/commands.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiD,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AASrF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAoB3D,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,CAG/F;AA4BD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,CAUlG;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,CA4BnG"}
|
package/lib/commands.js
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { MessageCommand, getActionFromMessage } from 'zhin.js';
|
|
2
|
-
import { buildChoiceFallbackMap, channelKey, normalizeRpsAction, parseChoicePayload, } from '@zhin.js/game-shared';
|
|
3
|
-
import { handleChoice, RPS_PREFIX } from './game-flow.js';
|
|
4
|
-
import { runRpsCommand } from './rps-command.js';
|
|
5
|
-
function registerPattern(plugin, pattern, desc, getServices) {
|
|
6
|
-
plugin.addCommand(new MessageCommand(pattern)
|
|
7
|
-
.desc(desc)
|
|
8
|
-
.action(async (message, result) => {
|
|
9
|
-
const services = getServices();
|
|
10
|
-
if (!services)
|
|
11
|
-
return '猜拳需要启用 database 配置。';
|
|
12
|
-
const raw = result.params.action ?? '';
|
|
13
|
-
return runRpsCommand(plugin, services, message, normalizeRpsAction(raw));
|
|
14
|
-
}));
|
|
15
|
-
}
|
|
16
|
-
export function registerCommands(plugin, getServices) {
|
|
17
|
-
registerPattern(plugin, 'rps [action:word]', '猜拳(rps)', getServices);
|
|
18
|
-
registerPattern(plugin, '猜拳 [action:word]', '猜拳(中文)', getServices);
|
|
19
|
-
}
|
|
20
|
-
async function resolveChoice(message, services) {
|
|
21
|
-
const action = getActionFromMessage(message);
|
|
22
|
-
if (!action)
|
|
23
|
-
return null;
|
|
24
|
-
const parsed = parseChoicePayload(action.payload, RPS_PREFIX);
|
|
25
|
-
if (parsed)
|
|
26
|
-
return { sessionId: parsed.sessionId, choiceId: parsed.choiceId };
|
|
27
|
-
const choiceId = action.id || action.payload;
|
|
28
|
-
if (!choiceId)
|
|
29
|
-
return null;
|
|
30
|
-
const ch = channelKey(message);
|
|
31
|
-
const session = await services.getActiveForUser(ch, message.$sender.id)
|
|
32
|
-
?? (action.sourceMessageId
|
|
33
|
-
? await services.getActiveByBoardMessageId(action.sourceMessageId)
|
|
34
|
-
: null);
|
|
35
|
-
if (!session || session.channel_key !== ch)
|
|
36
|
-
return null;
|
|
37
|
-
const valid = ['rock', 'paper', 'scissors', 'restart'];
|
|
38
|
-
if (!valid.includes(choiceId))
|
|
39
|
-
return null;
|
|
40
|
-
return { sessionId: session.id, choiceId };
|
|
41
|
-
}
|
|
42
|
-
export function registerInteractive(plugin, getServices) {
|
|
43
|
-
plugin.registerInteractiveHandler(`${RPS_PREFIX}:`, async (message) => {
|
|
44
|
-
const services = getServices();
|
|
45
|
-
if (!services)
|
|
46
|
-
return false;
|
|
47
|
-
const choice = await resolveChoice(message, services);
|
|
48
|
-
if (!choice)
|
|
49
|
-
return false;
|
|
50
|
-
const err = await handleChoice(plugin, services, message, choice.sessionId, choice.choiceId);
|
|
51
|
-
if (err)
|
|
52
|
-
await message.$reply?.(err);
|
|
53
|
-
return true;
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
export function registerTextFallback(plugin, getServices) {
|
|
57
|
-
plugin.addMiddleware(async (message, next) => {
|
|
58
|
-
const services = getServices();
|
|
59
|
-
if (!services)
|
|
60
|
-
return next();
|
|
61
|
-
const action = getActionFromMessage(message);
|
|
62
|
-
if (action?.payload.startsWith(`${RPS_PREFIX}:`))
|
|
63
|
-
return next();
|
|
64
|
-
const ch = channelKey(message);
|
|
65
|
-
const session = await services.getActiveForUser(ch, message.$sender.id);
|
|
66
|
-
if (!session || session.status !== 'active')
|
|
67
|
-
return next();
|
|
68
|
-
const raw = message.$raw?.trim() ?? '';
|
|
69
|
-
const n = /^(\d+)$/.exec(raw);
|
|
70
|
-
if (!n)
|
|
71
|
-
return next();
|
|
72
|
-
const map = buildChoiceFallbackMap(RPS_PREFIX, session.id, [
|
|
73
|
-
{ id: 'rock', label: '石头' },
|
|
74
|
-
{ id: 'paper', label: '布' },
|
|
75
|
-
{ id: 'scissors', label: '剪刀' },
|
|
76
|
-
]);
|
|
77
|
-
const payload = map[n[1]];
|
|
78
|
-
const parsed = payload ? parseChoicePayload(payload, RPS_PREFIX) : null;
|
|
79
|
-
if (!parsed || parsed.sessionId !== session.id)
|
|
80
|
-
return next();
|
|
81
|
-
const err = await handleChoice(plugin, services, message, session.id, parsed.choiceId);
|
|
82
|
-
if (err)
|
|
83
|
-
await message.$reply?.(err);
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
//# sourceMappingURL=commands.js.map
|
package/lib/commands.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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"}
|
package/lib/engine.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,QAAQ,CAAC;AAEhC,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;AAEpD,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAI/C,CAAC;AAQF,wBAAgB,aAAa,IAAI,OAAO,CAGvC;AAED,wBAAwB;AACxB,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAGrE;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAcrD;AAED,eAAO,MAAM,UAAU,IAAI,CAAC"}
|
package/lib/game-flow.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"game-flow.d.ts","sourceRoot":"","sources":["../src/game-flow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACL,UAAU,EAIV,KAAK,OAAO,EACb,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,EACrB,OAAO,EAAE,aAAa,EACtB,SAAS,CAAC,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;CAAE,GAC/D,OAAO,CAAC,IAAI,CAAC,CAqBf;AAED,wBAAsB,SAAS,CAC7B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,GACpB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAY7B;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,EACrB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA6CxB;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,GACpB,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED,OAAO,EAAE,UAAU,EAAE,CAAC"}
|
package/lib/hub-register.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hub-register.d.ts","sourceRoot":"","sources":["../src/hub-register.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiB,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,cAAc,GAAG,IAAI,GAAG,MAAM,IAAI,CAoBnF;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|
package/lib/hub-register.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { registerGame } from '@zhin.js/game-shared';
|
|
2
|
-
import { runRpsCommand, RPS_HELP } from './rps-command.js';
|
|
3
|
-
export function registerRpsHub(getServices) {
|
|
4
|
-
return registerGame({
|
|
5
|
-
id: 'rps',
|
|
6
|
-
title: '猜拳对决',
|
|
7
|
-
icon: '✊',
|
|
8
|
-
description: '石头剪刀布,三局两胜',
|
|
9
|
-
commandPrefix: '猜拳',
|
|
10
|
-
quickStart: '开始',
|
|
11
|
-
aliases: ['rps'],
|
|
12
|
-
menus: [
|
|
13
|
-
{ id: 'start', label: '🎮 开始对局', style: 'primary' },
|
|
14
|
-
{ id: 'continue', label: '🔄 继续' },
|
|
15
|
-
{ id: 'help', label: '📖 玩法说明' },
|
|
16
|
-
],
|
|
17
|
-
runAction: async (actionId, ctx) => {
|
|
18
|
-
const services = getServices();
|
|
19
|
-
if (!services)
|
|
20
|
-
return '猜拳需要启用 database 配置。';
|
|
21
|
-
return runRpsCommand(ctx.plugin, services, ctx.message, actionId);
|
|
22
|
-
},
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
export { RPS_HELP };
|
|
26
|
-
//# sourceMappingURL=hub-register.js.map
|
package/lib/hub-register.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hub-register.js","sourceRoot":"","sources":["../src/hub-register.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG3D,MAAM,UAAU,cAAc,CAAC,WAAwC;IACrE,OAAO,YAAY,CAAC;QAClB,EAAE,EAAE,KAAK;QACT,KAAK,EAAE,MAAM;QACb,IAAI,EAAE,GAAG;QACT,WAAW,EAAE,YAAY;QACzB,aAAa,EAAE,IAAI;QACnB,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,CAAC,KAAK,CAAC;QAChB,KAAK,EAAE;YACL,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;YACnD,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE;YAClC,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE;SACjC;QACD,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE;YACjC,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;YAC/B,IAAI,CAAC,QAAQ;gBAAE,OAAO,qBAAqB,CAAC;YAC5C,OAAO,aAAa,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACpE,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|
package/lib/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/lib/models.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAE9C,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC;AAErE,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,MAAM;QACd,YAAY,EAAE;YACZ,EAAE,EAAE,MAAM,CAAC;YACX,OAAO,EAAE,MAAM,CAAC;YAChB,QAAQ,EAAE,MAAM,CAAC;YACjB,YAAY,EAAE,MAAM,CAAC;YACrB,UAAU,EAAE,MAAM,CAAC;YACnB,WAAW,EAAE,MAAM,CAAC;YACpB,SAAS,EAAE,MAAM,CAAC;YAClB,WAAW,EAAE,MAAM,CAAC;YACpB,WAAW,EAAE,MAAM,CAAC;YACpB,QAAQ,EAAE,MAAM,CAAC;YACjB,KAAK,EAAE,MAAM,CAAC;YACd,MAAM,EAAE,gBAAgB,CAAC;YACzB,gBAAgB,EAAE,MAAM,CAAC;YACzB,UAAU,EAAE,MAAM,CAAC;YACnB,UAAU,EAAE,MAAM,CAAC;SACpB,CAAC;KACH;CACF;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;AAEnD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAkBnD"}
|
package/lib/rps-command.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rps-command.d.ts","sourceRoot":"","sources":["../src/rps-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAG/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,eAAO,MAAM,QAAQ,QAMT,CAAC;AAEb,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,EACrB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA0B7B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session-service.d.ts","sourceRoot":"","sources":["../src/session-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,EAAgB,MAAM,SAAS,CAAC;AAExF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAQ5D,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,WAAW;IAEtC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAKlE,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAMhF,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAIlD,yBAAyB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAa3E,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC;IAuB5D,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvE,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAalD;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,WAAW,GAAG,cAAc,CAE9D;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,eAAe,GAAG,WAAW,CAEzE"}
|
package/lib/view.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../src/view.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAuC,KAAK,OAAO,EAAE,MAAM,aAAa,CAAC;AAEhF,wBAAgB,YAAY,CAC1B,OAAO,EAAE,aAAa,EACtB,SAAS,CAAC,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;CAAE,GAC/D,WAAW,CA+Cb"}
|
package/plugin.yml
DELETED