xinyu-pro 0.21.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.
Files changed (96) hide show
  1. package/.env.example +21 -0
  2. package/README.md +36 -0
  3. package/app/api/chat/route.ts +84 -0
  4. package/app/api/generate-svg/route.ts +171 -0
  5. package/app/api/generate-theme/route.ts +137 -0
  6. package/app/api/plugins/bindings/route.ts +173 -0
  7. package/app/api/plugins/export/route.ts +122 -0
  8. package/app/api/plugins/export-xye/route.ts +156 -0
  9. package/app/api/plugins/files/route.ts +146 -0
  10. package/app/api/plugins/files-list/route.ts +168 -0
  11. package/app/api/plugins/files-upload/route.ts +101 -0
  12. package/app/api/plugins/files-write/route.ts +272 -0
  13. package/app/api/plugins/import/route.ts +140 -0
  14. package/app/api/plugins/import-package/route.ts +231 -0
  15. package/app/api/plugins/resources/route.ts +109 -0
  16. package/app/api/plugins/route.ts +308 -0
  17. package/app/api/plugins/scan/route.ts +280 -0
  18. package/app/api/plugins/storage/route.ts +146 -0
  19. package/app/api/sessions/route.ts +165 -0
  20. package/app/api/settings/route.ts +40 -0
  21. package/app/api/suggest-fields/route.ts +129 -0
  22. package/app/api/templates/route.ts +159 -0
  23. package/app/api/test-api/route.ts +63 -0
  24. package/app/editor/page.tsx +1466 -0
  25. package/app/extensions/create/page.tsx +1422 -0
  26. package/app/extensions/edit/[id]/page.tsx +2342 -0
  27. package/app/extensions/page.tsx +1572 -0
  28. package/app/extensions/tutorial/page.tsx +4258 -0
  29. package/app/favicon.ico +0 -0
  30. package/app/fonts/GeistMonoVF.woff +0 -0
  31. package/app/fonts/GeistVF.woff +0 -0
  32. package/app/game/[id]/page.tsx +996 -0
  33. package/app/globals.css +3 -0
  34. package/app/layout.tsx +26 -0
  35. package/app/loading.tsx +26 -0
  36. package/app/page.tsx +345 -0
  37. package/app/settings/page.tsx +1490 -0
  38. package/bin/cli.js +262 -0
  39. package/components/ChatInput.tsx +106 -0
  40. package/components/ChatWindow.tsx +52 -0
  41. package/components/FullPageLoader.tsx +107 -0
  42. package/components/LoadingDots.tsx +20 -0
  43. package/components/MathCurveLoader.tsx +173 -0
  44. package/components/MessageBubble.tsx +147 -0
  45. package/components/WorldCardPreview.tsx +98 -0
  46. package/components/WorldCardUploader.tsx +58 -0
  47. package/components/ui/ConfirmDialog.tsx +135 -0
  48. package/components/ui/PageHeader.tsx +99 -0
  49. package/components/ui/PermissionConflictDialog.tsx +206 -0
  50. package/components/ui/PluginConfigForm.tsx +192 -0
  51. package/components/ui/PluginFloatingLayer.tsx +52 -0
  52. package/components/ui/PluginIcon.tsx +53 -0
  53. package/components/ui/PluginModalRenderer.tsx +185 -0
  54. package/components/ui/PluginProvider.tsx +1038 -0
  55. package/components/ui/PluginSlotRenderer.tsx +76 -0
  56. package/components/ui/ThemeCustomizer.tsx +174 -0
  57. package/components/ui/ThemeProvider.tsx +125 -0
  58. package/components/ui/ThemeSwitcher.tsx +140 -0
  59. package/components/ui/ToastProvider.tsx +141 -0
  60. package/lib/builtin-plugins.ts +11 -0
  61. package/lib/db-init.ts +35 -0
  62. package/lib/db.ts +244 -0
  63. package/lib/manifest-parser.ts +185 -0
  64. package/lib/parseWorldCard.ts +110 -0
  65. package/lib/plugin-dom-sandbox.ts +327 -0
  66. package/lib/plugin-events.ts +88 -0
  67. package/lib/plugin-files.ts +186 -0
  68. package/lib/plugin-html-sanitizer.ts +79 -0
  69. package/lib/plugin-resource-tracker.ts +175 -0
  70. package/lib/plugin-runtime.ts +2287 -0
  71. package/lib/plugin-security.ts +151 -0
  72. package/lib/plugin-types.ts +416 -0
  73. package/lib/prompt-builder.ts +55 -0
  74. package/lib/router-history.ts +119 -0
  75. package/lib/storage.ts +381 -0
  76. package/lib/themes.ts +129 -0
  77. package/lib/types.ts +117 -0
  78. package/lib/version.ts +55 -0
  79. package/next.config.mjs +43 -0
  80. package/package.json +56 -0
  81. package/plugins/xinyu.bag-system.xye +0 -0
  82. package/plugins/xinyu.cache-optimizer.xye +0 -0
  83. package/plugins/xinyu.dice-arbiter.xye +0 -0
  84. package/plugins/xinyu.game-auto-start-choices.xye +0 -0
  85. package/plugins/xinyu.markdown-render.xye +0 -0
  86. package/plugins/xinyu.slot-ui-beautify.xye +0 -0
  87. package/plugins/xinyu.world-info.xye +0 -0
  88. package/postcss.config.mjs +8 -0
  89. package/public/templates/atlantis.svg +63 -0
  90. package/public/templates/cyber-city.svg +68 -0
  91. package/public/templates/jianghu.svg +69 -0
  92. package/public/templates//351/255/224/346/263/225/344/270/226/347/225/214.svg +137 -0
  93. package/styles/themes.css +111 -0
  94. package/tailwind.config.ts +18 -0
  95. package/tsconfig.json +26 -0
  96. package/version.json +6 -0
@@ -0,0 +1,175 @@
1
+ // lib/plugin-resource-tracker.ts - 插件资源追踪器
2
+ // 负责追踪每个插件创建的所有资源,在插件卸载时自动清理
3
+
4
+ /** 单个事件监听器记录 */
5
+ interface TrackedEventListener {
6
+ element: HTMLElement | Window | Document;
7
+ event: string;
8
+ handler: EventListener;
9
+ }
10
+
11
+ /** 单个插件的资源集合 */
12
+ interface PluginResources {
13
+ pluginId: string;
14
+ elements: Map<string, HTMLElement>;
15
+ styleTags: Map<string, HTMLStyleElement>;
16
+ eventListeners: TrackedEventListener[];
17
+ slotRegistrationIds: string[];
18
+ modalIds: string[];
19
+ intervals: ReturnType<typeof setInterval>[];
20
+ timeouts: ReturnType<typeof setTimeout>[];
21
+ hostEventHandlers: Array<{ eventName: string; handler: (...args: unknown[]) => unknown }>;
22
+ }
23
+
24
+ /** 插件资源追踪器 */
25
+ export class PluginResourceTracker {
26
+ private resources: Map<string, PluginResources> = new Map();
27
+
28
+ /** 创建或获取插件的资源追踪 */
29
+ getOrCreate(pluginId: string): PluginResources {
30
+ if (!this.resources.has(pluginId)) {
31
+ this.resources.set(pluginId, {
32
+ pluginId,
33
+ elements: new Map(),
34
+ styleTags: new Map(),
35
+ eventListeners: [],
36
+ slotRegistrationIds: [],
37
+ modalIds: [],
38
+ intervals: [],
39
+ timeouts: [],
40
+ hostEventHandlers: [],
41
+ });
42
+ }
43
+ return this.resources.get(pluginId)!;
44
+ }
45
+
46
+ /** 获取插件的资源追踪(不存在返回 undefined) */
47
+ get(pluginId: string): PluginResources | undefined {
48
+ return this.resources.get(pluginId);
49
+ }
50
+
51
+ // ---- DOM 元素追踪 ----
52
+
53
+ trackElement(pluginId: string, id: string, element: HTMLElement): void {
54
+ const res = this.getOrCreate(pluginId);
55
+ res.elements.set(id, element);
56
+ }
57
+
58
+ untrackElement(pluginId: string, id: string): void {
59
+ const res = this.resources.get(pluginId);
60
+ if (res) {
61
+ res.elements.delete(id);
62
+ }
63
+ }
64
+
65
+ getElement(pluginId: string, id: string): HTMLElement | undefined {
66
+ return this.resources.get(pluginId)?.elements.get(id);
67
+ }
68
+
69
+ // ---- 样式标签追踪 ----
70
+
71
+ trackStyle(pluginId: string, id: string, styleElement: HTMLStyleElement): void {
72
+ const res = this.getOrCreate(pluginId);
73
+ res.styleTags.set(id, styleElement);
74
+ }
75
+
76
+ untrackStyle(pluginId: string, id: string): void {
77
+ const res = this.resources.get(pluginId);
78
+ if (res) {
79
+ res.styleTags.delete(id);
80
+ }
81
+ }
82
+
83
+ // ---- 事件监听器追踪 ----
84
+
85
+ trackEventListener(pluginId: string, listener: TrackedEventListener): void {
86
+ const res = this.getOrCreate(pluginId);
87
+ res.eventListeners.push(listener);
88
+ }
89
+
90
+ // ---- 插槽注册追踪 ----
91
+
92
+ trackSlotRegistration(pluginId: string, registrationId: string): void {
93
+ const res = this.getOrCreate(pluginId);
94
+ res.slotRegistrationIds.push(registrationId);
95
+ }
96
+
97
+ // ---- 模态框追踪 ----
98
+
99
+ trackModal(pluginId: string, modalId: string): void {
100
+ const res = this.getOrCreate(pluginId);
101
+ res.modalIds.push(modalId);
102
+ }
103
+
104
+ // ---- 定时器追踪 ----
105
+
106
+ trackInterval(pluginId: string, id: ReturnType<typeof setInterval>): void {
107
+ const res = this.getOrCreate(pluginId);
108
+ res.intervals.push(id);
109
+ }
110
+
111
+ trackTimeout(pluginId: string, id: ReturnType<typeof setTimeout>): void {
112
+ const res = this.getOrCreate(pluginId);
113
+ res.timeouts.push(id);
114
+ }
115
+
116
+ // ---- 宿主事件追踪 ----
117
+
118
+ trackHostEventHandler(pluginId: string, eventName: string, handler: (...args: unknown[]) => unknown): void {
119
+ const res = this.getOrCreate(pluginId);
120
+ res.hostEventHandlers.push({ eventName, handler });
121
+ }
122
+
123
+ // ---- 清理 ----
124
+
125
+ /** 清理插件的所有资源 */
126
+ cleanup(pluginId: string): void {
127
+ const res = this.resources.get(pluginId);
128
+ if (!res) return;
129
+
130
+ // 1. 移除所有 DOM 元素
131
+ res.elements.forEach((el) => {
132
+ try {
133
+ if (el.parentNode) {
134
+ el.parentNode.removeChild(el);
135
+ }
136
+ } catch (e) {
137
+ console.warn(`[ResourceTracker] 移除元素失败 (${pluginId}):`, e);
138
+ }
139
+ });
140
+
141
+ // 2. 移除所有样式标签
142
+ res.styleTags.forEach((tag) => {
143
+ try {
144
+ if (tag.parentNode) {
145
+ tag.parentNode.removeChild(tag);
146
+ }
147
+ } catch (e) {
148
+ console.warn(`[ResourceTracker] 移除样式失败 (${pluginId}):`, e);
149
+ }
150
+ });
151
+
152
+ // 3. 移除所有事件监听
153
+ res.eventListeners.forEach(({ element, event, handler }) => {
154
+ try {
155
+ element.removeEventListener(event, handler);
156
+ } catch (e) {
157
+ console.warn(`[ResourceTracker] 移除事件监听失败 (${pluginId}):`, e);
158
+ }
159
+ });
160
+
161
+ // 4. 清除所有定时器
162
+ res.intervals.forEach((id) => clearInterval(id));
163
+ res.timeouts.forEach((id) => clearTimeout(id));
164
+
165
+ // 5. 删除追踪记录
166
+ this.resources.delete(pluginId);
167
+ }
168
+
169
+ /** 重置所有资源 */
170
+ reset(): void {
171
+ this.resources.forEach((_, pluginId) => {
172
+ this.cleanup(pluginId);
173
+ });
174
+ }
175
+ }