@inkweave/plugins 1.0.1 → 1.1.3
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 +374 -0
- package/dist/cdButton/cooldownState.d.ts +8 -0
- package/dist/image/index.d.ts +1 -1
- package/dist/index.cjs +1 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +7 -8
- package/dist/index.js +260 -255
- package/dist/index.js.map +1 -1
- package/dist/plugins.css +1 -0
- package/package.json +19 -14
package/README.md
ADDED
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
# InkWeave Plugins
|
|
2
|
+
|
|
3
|
+
InkWeave 插件扩展包,为交互式故事提供丰富的功能增强。
|
|
4
|
+
|
|
5
|
+
## 内置插件
|
|
6
|
+
|
|
7
|
+
| 插件 | 功能说明 |
|
|
8
|
+
| ----------------- | ------------------------ |
|
|
9
|
+
| Image | 显示场景背景图片 |
|
|
10
|
+
| Audio | 播放背景音乐和音效 |
|
|
11
|
+
| Linkopen | 打开外部网页链接 |
|
|
12
|
+
| FadeEffect | 文字逐行淡入效果 |
|
|
13
|
+
| ScrollAfterChoice | 选择后自动滚动到最新内容 |
|
|
14
|
+
| AutoButton | 隐藏按钮,定时自动触发 |
|
|
15
|
+
| CdButton | 冷却按钮,显示倒计时 |
|
|
16
|
+
| Memory | 存档管理(保存/读取) |
|
|
17
|
+
| Autosave | 自动保存游戏进度 |
|
|
18
|
+
|
|
19
|
+
### 内容扩展
|
|
20
|
+
|
|
21
|
+
#### Image - 图片显示
|
|
22
|
+
|
|
23
|
+
在故事中显示背景图片或场景插图。
|
|
24
|
+
|
|
25
|
+
**Ink 语法:**
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
#image:path/to/image.png
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
清除当前图片:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
#image:
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**效果:** 设置当前场景的背景图片,图片路径相对于 `basePath`。
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
#### Audio - 音频播放
|
|
42
|
+
|
|
43
|
+
支持背景音乐和音效播放。
|
|
44
|
+
|
|
45
|
+
**Ink 语法:**
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
#music:audio/bgm.mp3 // 播放背景音乐(循环)
|
|
49
|
+
#sound:audio/effect.wav // 播放音效(单次)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
停止播放:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
#music: // 停止背景音乐
|
|
56
|
+
#sound: // 停止音效
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**效果:**
|
|
60
|
+
|
|
61
|
+
- `#music` 循环播放背景音乐,适合场景氛围
|
|
62
|
+
- `#sound` 播放单次音效,适合点击、过渡等
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
#### Linkopen - 外部链接
|
|
67
|
+
|
|
68
|
+
在故事中打开外部网页链接。
|
|
69
|
+
|
|
70
|
+
**Ink 语法:**
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
#linkopen:https://example.com
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**效果:** 在新标签页打开指定 URL(仅支持 http/https 协议,安全限制)。
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
### 视觉效果
|
|
81
|
+
|
|
82
|
+
#### FadeEffect - 文字淡入
|
|
83
|
+
|
|
84
|
+
为文字添加逐行淡入效果,营造阅读节奏感。
|
|
85
|
+
|
|
86
|
+
**Ink 语法:**
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
#linedelay:0.05 // 设置每行延迟 0.05 秒
|
|
90
|
+
#linedelay:0 // 关闭淡入效果(立即显示全部文字)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**效果:** 文字按设定速度逐行淡入显示,选项按钮会在文字完全显示后才出现。
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
#### ScrollAfterChoice - 选择后滚动
|
|
98
|
+
|
|
99
|
+
选择选项后自动滚动到最新内容位置。
|
|
100
|
+
|
|
101
|
+
**Ink 语法:** 无需语法,自动生效。
|
|
102
|
+
|
|
103
|
+
**效果:** 确保用户始终看到最新的故事内容,适合长篇故事。
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
### 按钮增强
|
|
108
|
+
|
|
109
|
+
#### AutoButton - 自动按钮
|
|
110
|
+
|
|
111
|
+
隐藏按钮,倒计时后自动触发。
|
|
112
|
+
|
|
113
|
+
**Ink 语法:**
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
+ [按钮文本#auto:3]
|
|
117
|
+
-> next_scene
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**参数:** `#auto:秒数` - 自动触发的时间间隔
|
|
121
|
+
|
|
122
|
+
**效果:**
|
|
123
|
+
|
|
124
|
+
- 按钮隐藏不可见
|
|
125
|
+
- 指定秒数后自动执行该选项
|
|
126
|
+
- 适合倒计时跳转、跳过过场、自动推进剧情
|
|
127
|
+
|
|
128
|
+
**组合用法:** 同时提供手动和自动选项:
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
+ [跳过过场#auto:5]
|
|
132
|
+
-> next
|
|
133
|
+
+ [点击继续]
|
|
134
|
+
-> next
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
#### CdButton - 冷却按钮
|
|
140
|
+
|
|
141
|
+
按钮显示冷却倒计时,冷却期间禁用。
|
|
142
|
+
|
|
143
|
+
**Ink 语法:**
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
+ [攻击#cd:10]
|
|
147
|
+
-> attack
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**参数:** `#cd:秒数` - 冷却时间
|
|
151
|
+
|
|
152
|
+
**效果:**
|
|
153
|
+
|
|
154
|
+
- 显示按钮文本和剩余秒数:`攻击 (10)`
|
|
155
|
+
- 冷却期间按钮禁用,不可点击
|
|
156
|
+
- 适合技能冷却、回复限制等场景
|
|
157
|
+
|
|
158
|
+
**模板定制:** 初始化时可配置 `cdTemplate`:
|
|
159
|
+
|
|
160
|
+
```js
|
|
161
|
+
InkWeave.init({
|
|
162
|
+
cdTemplate: '{text} [{time}s]', // 显示:攻击 [10s]
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
### 存档系统
|
|
169
|
+
|
|
170
|
+
#### Memory - 存档管理
|
|
171
|
+
|
|
172
|
+
提供存档、读档功能,支持 localStorage 和 sessionStorage。
|
|
173
|
+
|
|
174
|
+
**API:**
|
|
175
|
+
|
|
176
|
+
```js
|
|
177
|
+
import { memory } from '@inkweave/plugins';
|
|
178
|
+
|
|
179
|
+
memory.save(1, ink); // 保存到槽位 1
|
|
180
|
+
memory.load(saveData, ink); // 加载存档
|
|
181
|
+
memory.show(title); // 获取指定故事的存档列表
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**配置:**
|
|
185
|
+
|
|
186
|
+
```js
|
|
187
|
+
loadMemory(); // 默认 localStorage
|
|
188
|
+
// 或在 init 时设置:memory_format: 'session'
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
#### Autosave - 自动存档
|
|
194
|
+
|
|
195
|
+
在指定位置自动保存游戏进度。
|
|
196
|
+
|
|
197
|
+
**Ink 语法:**
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
#autosave
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**效果:** 执行到此标签时自动保存到槽位 1。
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## 插件开发规范
|
|
208
|
+
|
|
209
|
+
### 插件结构
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
src/
|
|
213
|
+
├── myPlugin/
|
|
214
|
+
│ ├── index.ts # 入口,导出 load 函数
|
|
215
|
+
│ ├── MyComponent.tsx # 可选,React 组件
|
|
216
|
+
│ └── utils.ts # 可选,辅助逻辑
|
|
217
|
+
│
|
|
218
|
+
└── index.ts # 导出所有插件
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### 入口文件规范
|
|
222
|
+
|
|
223
|
+
```ts
|
|
224
|
+
// index.ts
|
|
225
|
+
import { Tags, ChoiceParser, Patches, type InkStory } from '@inkweave/core';
|
|
226
|
+
import { ChoiceRegistry } from '@inkweave/react';
|
|
227
|
+
|
|
228
|
+
const options = {
|
|
229
|
+
my_option: 'default_value',
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const load = () => {
|
|
233
|
+
// 注册功能...
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
export default load;
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### 核心扩展点
|
|
240
|
+
|
|
241
|
+
#### 1. Tags - 内容标签
|
|
242
|
+
|
|
243
|
+
处理 ink 脚本中的 `#tag:value` 标签。
|
|
244
|
+
|
|
245
|
+
```ts
|
|
246
|
+
Tags.add('mytag', (val: string | null | undefined, ink: InkStory) => {
|
|
247
|
+
// val 是标签值,ink 是故事实例
|
|
248
|
+
if (val) {
|
|
249
|
+
ink.options.my_option = val;
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
**使用场景:** 图片、音频、链接、配置修改等。
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
#### 2. ChoiceParser - 选项解析
|
|
259
|
+
|
|
260
|
+
解析选项按钮的标签 `[文本#tag:value]`。
|
|
261
|
+
|
|
262
|
+
```ts
|
|
263
|
+
ChoiceParser.add('mytype', (choice, val) => {
|
|
264
|
+
choice.type = 'mytype'; // 设置按钮类型
|
|
265
|
+
choice.val = val; // 保存参数值
|
|
266
|
+
});
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
**配合组件注册:**
|
|
270
|
+
|
|
271
|
+
```ts
|
|
272
|
+
ChoiceRegistry.register('mytype', MyButtonComponent);
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
**使用场景:** 特殊按钮类型(自动、冷却、禁用等)。
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
#### 3. Patches - 实例扩展
|
|
280
|
+
|
|
281
|
+
扩展 InkStory 实例的能力和生命周期。
|
|
282
|
+
|
|
283
|
+
```ts
|
|
284
|
+
Patches.add(function (this: InkStoryContext) {
|
|
285
|
+
// 添加属性
|
|
286
|
+
this.myProperty = 'value';
|
|
287
|
+
|
|
288
|
+
// 添加存档字段
|
|
289
|
+
this.save_label.push('myProperty');
|
|
290
|
+
|
|
291
|
+
// 清理钩子(故事重置时)
|
|
292
|
+
this.clears.push(() => {
|
|
293
|
+
this.myProperty = '';
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
// 销毁钩子(实例销毁时)
|
|
297
|
+
this.cleanups.push(() => {
|
|
298
|
+
// 清理资源...
|
|
299
|
+
});
|
|
300
|
+
}, options);
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**使用场景:** 添加状态、生命周期管理、存档字段。
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
#### 4. ChoiceRegistry - 按钮组件
|
|
308
|
+
|
|
309
|
+
注册自定义 React 选项按钮组件。
|
|
310
|
+
|
|
311
|
+
```tsx
|
|
312
|
+
// MyButton.tsx
|
|
313
|
+
import { memo } from 'react';
|
|
314
|
+
import type { ChoiceComponentProps } from '@inkweave/react';
|
|
315
|
+
|
|
316
|
+
const MyButton: React.FC<ChoiceComponentProps> = ({ choice, onClick, className, children }) => {
|
|
317
|
+
return (
|
|
318
|
+
<button className={className} onClick={onClick}>
|
|
319
|
+
{children}
|
|
320
|
+
{/* 自定义渲染 */}
|
|
321
|
+
</button>
|
|
322
|
+
);
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
export default memo(MyButton);
|
|
326
|
+
|
|
327
|
+
// index.ts
|
|
328
|
+
ChoiceRegistry.register('mytype', MyButton);
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
### 类型声明扩展
|
|
334
|
+
|
|
335
|
+
当插件添加新属性时,需要扩展类型声明:
|
|
336
|
+
|
|
337
|
+
```ts
|
|
338
|
+
declare module '@inkweave/core' {
|
|
339
|
+
interface InkStory {
|
|
340
|
+
myProperty: string;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
### 开发建议
|
|
348
|
+
|
|
349
|
+
1. **单一职责**:每个插件专注一个功能
|
|
350
|
+
2. **命名规范**:
|
|
351
|
+
- 标签:小写,无特殊字符(`#image`、`#music`)
|
|
352
|
+
- 类型:简短描述性(`cd`、`auto`)
|
|
353
|
+
3. **配置可定制**:通过 options 提供默认配置
|
|
354
|
+
4. **生命周期管理**:
|
|
355
|
+
- 使用 `clears` 处理故事重置
|
|
356
|
+
- 使用 `cleanups` 处理实例销毁
|
|
357
|
+
5. **存档兼容**:新增状态需添加到 `save_label`
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
### 插件导出
|
|
362
|
+
|
|
363
|
+
在 `src/index.ts` 中导出:
|
|
364
|
+
|
|
365
|
+
```ts
|
|
366
|
+
export { default as loadMyPlugin } from './myPlugin';
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
使用方按需加载:
|
|
370
|
+
|
|
371
|
+
```ts
|
|
372
|
+
import { loadMyPlugin } from '@inkweave/plugins';
|
|
373
|
+
loadMyPlugin();
|
|
374
|
+
```
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function getCooldownKey(choice: {
|
|
2
|
+
type: string;
|
|
3
|
+
text: string;
|
|
4
|
+
val?: string;
|
|
5
|
+
}): string;
|
|
6
|
+
export declare function isCooldownActive(key: string): boolean;
|
|
7
|
+
export declare function getRemainingSeconds(key: string): number;
|
|
8
|
+
export declare function setCooldown(key: string, seconds: number): void;
|
package/dist/image/index.d.ts
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -1,17 +1,2 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
#inkweave-contents div,
|
|
3
|
-
#inkweave-choices {
|
|
4
|
-
opacity: 0;
|
|
5
|
-
animation: inkFadeIn 0.5s forwards;
|
|
6
|
-
animation-delay: var(--delay, 0s);
|
|
7
|
-
}
|
|
8
|
-
@keyframes inkFadeIn {
|
|
9
|
-
from {
|
|
10
|
-
opacity: 0;
|
|
11
|
-
}
|
|
12
|
-
to {
|
|
13
|
-
opacity: 1;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
`,R={linedelay:.05},u=_.create(t=>({contentComplete:!0,last_content:"",setContentComplete:e=>t({contentComplete:e}),setLastContent:e=>{if(e.length===0){t({last_content:""});return}const s=e[e.length-1];t({last_content:s})}}));let g=null;const J=()=>{g||(g=document.createElement("style"),g.textContent=D,document.head.appendChild(g)),a.Patches.add(function(){const t=this.choose,e=this;this.choose=function(n){return e.options.linedelay!=0&&(u.getState().setContentComplete(!1),u.getState().setLastContent(e.contents)),t.call(e,n)},Object.defineProperty(this,"visibleLines",{get(){const n=u.getState().last_content;return e.contents.lastIndexOf(n)}}),Object.defineProperty(this,"choicesCanShow",{get(){return a.createSelectors(u).use.contentComplete()}});let s=null;const o=a.contentsStore.subscribe(()=>{e.options.linedelay!=0&&(s&&clearTimeout(s),s=setTimeout(()=>{u.getState().setContentComplete(!0)},(e.contents.length-e.visibleLines)*e.options.linedelay*1e3))});this.cleanups.push(()=>{o(),s&&clearTimeout(s)}),this.clears.push(()=>{e.options.linedelay!=0&&u.getState().setContentComplete(!1),u.getState().setLastContent([])})},R)},W=()=>{a.Patches.add(function(){let t=null;const e=a.choicesStore.subscribe(()=>{t&&clearTimeout(t),t=setTimeout(()=>{const s=document.querySelector("ul#inkweave-choices > li:last-child");if(s){const o=document.querySelector("#inkweave-story");o==null||o.scrollTo({top:s.offsetTop,behavior:"smooth"})}},0)});this.cleanups.push(()=>{e(),t&&clearTimeout(t)})},{})},N=["http:","https:"],B=()=>{a.Tags.add("linkopen",t=>{if(t){try{const e=new URL(t);if(!N.includes(e.protocol)){console.warn("InkWeave: Blocked unsafe URL protocol:",e.protocol);return}}catch{console.warn("InkWeave: Invalid URL:",t);return}window.open(t,"_blank","noopener,noreferrer")}})},U=({val:t,onClick:e,className:s="",children:o})=>{const n=c.useRef(null),i=parseFloat(t||"0");return c.useEffect(()=>{if(!(i<=0))return n.current=setInterval(()=>{e()},i*1e3),()=>{n.current&&clearInterval(n.current)}},[i,e]),h.jsx("a",{className:`inkweave-btn ${s}`,style:{display:"none"},children:o})},z=c.memo(U),G=()=>{a.ChoiceParser.add("auto",(t,e)=>{t.type="auto",t.val=e}),C.ChoiceComponents.register("auto",z),a.Patches.add(null,{})},H=({val:t,onClick:e,className:s="",children:o})=>{const[n,i]=c.useState(!1),d=parseFloat(t||"0"),p=()=>{n||(e(),i(!0),setTimeout(()=>{i(!1)},d*1e3))};return h.jsx("a",{className:`inkweave-btn ${s} ${n?"disabled":""}`,onClick:p,children:o})},K=c.memo(H),Q=()=>{a.ChoiceParser.add("cd",(t,e)=>{t.type="cd",t.val=e}),C.ChoiceComponents.register("cd",K),a.Patches.add(null,{})},X={autosave_enabled:!0},Y=()=>{a.Tags.add("autosave",(t,e)=>{e.options.autosave_enabled&&w.save(2,e)}),a.Patches.add(null,X)};exports.Image=j;exports.loadAudio=x;exports.loadAutoButton=G;exports.loadAutosave=Y;exports.loadCdButton=Q;exports.loadFadeEffect=J;exports.loadImage=q;exports.loadLinkopen=B;exports.loadMemory=k;exports.loadScrollafterchoice=W;exports.memory=w;exports.useStoryImage=m;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("@inkweave/core"),p=require("@inkweave/react"),y=require("react/jsx-runtime"),c=require("react"),C=require("zustand"),N=require("zustand/middleware"),n=class n{static get sound(){return n._sound}static get music(){return n._music}static get sound_handler(){return n._sound_handler}static get music_handler(){return n._music_handler}static set_music(e){n._music=new Audio(e),n._music.loop=!0,n._music_handler=()=>{var s;(s=n._music)==null||s.play()},n._music.addEventListener("canplaythrough",n._music_handler)}static set_sound(e){n._sound=new Audio(e),n._sound_handler=()=>{var s;(s=n._sound)==null||s.play()},n._sound.addEventListener("canplaythrough",n._sound_handler)}static cleanupSound(){n._sound&&(n._sound.pause(),n._sound.currentTime=0,n._sound.removeEventListener("canplaythrough",n._sound_handler),n._sound.src=""),n._sound=null,n._sound_handler=()=>{}}static cleanupMusic(){n._music&&(n._music.pause(),n._music.currentTime=0,n._music.removeEventListener("canplaythrough",n._music_handler),n._music.src=""),n._music=null,n._music_handler=()=>{}}};n._sound=null,n._music=null,n._sound_handler=()=>{},n._music_handler=()=>{};let l=n;const T=(t,e)=>e&&"resolveFilename"in e?e.resolveFilename(t):t,j=()=>{r.Tags.add("sound",(t,e)=>{t?(l.cleanupSound(),l.set_sound(T(t,e.options.fileHandler))):l.cleanupSound()}),r.Tags.add("music",(t,e)=>{t?(l.cleanupMusic(),l.set_music(T(t,e.options.fileHandler))):l.cleanupMusic()}),r.Patches.add(function(){this.audio=l,this.cleanups.push(()=>{l.cleanupSound(),l.cleanupMusic()})},{})},q=({choice:t,onClick:e,className:s="",children:o})=>{const a=c.useRef(null),i=c.useRef(e),u=parseFloat(t.val||"0");i.current=e,c.useEffect(()=>{if(!(u<=0))return a.current=setInterval(()=>{i.current()},u*1e3),()=>{a.current&&clearInterval(a.current)}},[u]);const g=`${p.choiceStyles.button} ${s}`.trim();return y.jsx("a",{className:g,style:{display:"none"},children:o})},D=c.memo(q),k=()=>{r.ChoiceParser.add("auto",(t,e)=>{t.type="auto",t.val=e}),p.ChoiceRegistry.register("auto",D),r.Patches.add(null,{})},A={local:localStorage,session:sessionStorage};let M="local";const v=()=>A[M];class J{constructor(e){this.data=JSON.stringify(e),this.timestamp=new Intl.DateTimeFormat(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}).format(Date.now()),this.meta="autogenerated"}}const _=C.create()(N.persist((t,e)=>({storage:new Map,setStorage:(s,o,a)=>{const i=new Map(e().storage),u=[...i.get(s)||[]];u[o]=new J(a),i.set(s,u),t({storage:i})},changeFormat:s=>{M=s}}),{name:"inkStory",storage:{getItem:t=>{const e=v().getItem(t);if(!e)return null;try{const{state:s}=JSON.parse(e);return{state:{...s,storage:new Map(s.storage)}}}catch(s){return console.error("InkWeave: Failed to parse storage data:",s),null}},setItem:(t,e)=>{const s=JSON.stringify({state:{...e.state,storage:Array.from(e.state.storage.entries())}});v().setItem(t,s)},removeItem:t=>{v().removeItem(t)}}})),L={memory_format:"local"},W=t=>_(e=>e.storage.get(t)||null),U=(t,e)=>{const s={state:e.story.state.toJson()};e.save_label.forEach(o=>{const a=e[o];o in e&&a!==void 0&&(typeof a=="string"||typeof a=="number"||typeof a=="boolean"||Array.isArray(a))&&(s[o]=a)}),_.getState().setStorage(e.title,t,s)},B=(t,e)=>{let s=null;try{s=JSON.parse(t)}catch(o){console.error("InkWeave: Failed to parse save data:",o);return}s&&(e.story.state.LoadJson(s.state),e.clear(),e.save_label.forEach(o=>{o in e&&typeof e[o]<"u"&&o in s&&(e[o]=s[o])}),e.continue())},z=()=>{r.Patches.add(()=>{_.getState().changeFormat(L.memory_format)},L)},P={save:U,load:B,show:W},K={autosave_enabled:!0},G=()=>{r.Tags.add("autosave",(t,e)=>{e.options.autosave_enabled&&P.save(1,e)}),r.Patches.add(null,K)},w=new Map;function H(t){return`${t.type}_${t.text}_${t.val||""}`}function Q(t){const e=w.get(t)||0;return Date.now()<e}function X(t){const e=w.get(t)||0,s=Math.max(0,e-Date.now());return Math.ceil(s/1e3)}function Y(t,e){w.set(t,Date.now()+e*1e3)}const Z=({choice:t,onClick:e,className:s="",children:o})=>{var $,b;const a=parseFloat(t.val||"0"),i=H(t),u=p.useStory(),[,g]=c.useState(0),f=c.useRef(!0),m=Q(i),I=X(i);c.useEffect(()=>()=>{f.current=!1},[]),c.useEffect(()=>{if(!m)return;const S=setInterval(()=>{f.current&&g(O=>O+1)},1e3);return()=>clearInterval(S)},[m]);const E=c.useCallback(()=>{m||(e(),Y(i,a),g(S=>S+1))},[m,a,e,i]),R=`${(($=p.choiceStyles)==null?void 0:$.button)||""} ${s} ${m&&((b=p.choiceStyles)==null?void 0:b.disabled)||""}`.trim(),x=u.options.cdTemplate||"{text} ({time})",F=m&&I>0?x.replace("{text}",String(o)).replace("{time}",String(I)):o;return y.jsx("a",{className:R,onClick:E,children:F})},V=c.memo(Z),ee={cdTemplate:"{text} ({time})"},te=()=>{r.ChoiceParser.add("cd",(t,e)=>{t.type="cd",t.val=e}),p.ChoiceRegistry.register("cd",V),r.Patches.add(null,ee)},se={linedelay:.05},d=C.create(t=>({contentComplete:!0,last_content:"",setContentComplete:e=>t({contentComplete:e}),setLastContent:e=>{if(e.length===0){t({last_content:""});return}const s=e[e.length-1];t({last_content:s})}})),ne=()=>{r.Tags.add("linedelay",(t,e)=>{if(t!=null){const s=parseFloat(t);Number.isNaN(s)||(e.options.linedelay=s,s===0&&d.getState().setContentComplete(!0))}}),r.Patches.add(function(){const t=this.choose,e=this;this.choose=a=>(e.options.linedelay!==0&&(d.getState().setContentComplete(!1),d.getState().setLastContent(e.contents)),t.call(e,a)),Object.defineProperty(this,"visibleLines",{get(){const a=d.getState().last_content;return a?e.contents.lastIndexOf(a):-1}}),Object.defineProperty(this,"choicesCanShow",{get(){return r.createSelectors(d).use.contentComplete()}});let s=null;const o=r.contentsStore.subscribe(()=>{if(s&&clearTimeout(s),e.options.linedelay===0){d.getState().setContentComplete(!0);return}s=setTimeout(()=>{d.getState().setContentComplete(!0)},Math.max(0,(e.contents.length-e.visibleLines)*e.options.linedelay*1e3))});this.cleanups.push(()=>{o(),s&&clearTimeout(s)}),this.clears.push(()=>{e.options.linedelay!==0&&d.getState().setContentComplete(!1),d.getState().setLastContent([])})},se)},oe="_container_1a16a_1",ae={container:oe},re=({className:t="",fallback:e=null})=>{const s=h(m=>m.image),[o,a]=c.useState(!1);c.useEffect(()=>{a(!1)},[]);const i=c.useRef(s);i.current=s;const u=c.useCallback(()=>{a(!0),console.warn(`InkWeave: Failed to load image: ${i.current}`)},[]),g=c.useCallback(()=>{a(!1)},[]),f=`${ae.container} ${t}`.trim();return s?o?e?y.jsx("div",{className:f,children:e}):null:y.jsx("div",{className:f,children:y.jsx("img",{src:s,alt:"",onError:u,onLoad:g})}):null},ce=c.memo(re),h=C.create(t=>({image:"",setImage:e=>t({image:e})})),ie=(t,e)=>e&&"resolveFilename"in e?e.resolveFilename(t):t,le=()=>{r.Tags.add("image",(t,e)=>{t?h.getState().setImage(ie(t,e.options.fileHandler)):h.getState().setImage("")}),r.Patches.add(function(){Object.defineProperty(this,"image",{get(){return h.getState().image},set(t){h.getState().setImage(t)}}),this.save_label.push("image"),this.clears.push(()=>{this.image=""})},{})},ue=["http:","https:"],de=()=>{r.Tags.add("linkopen",t=>{if(t){try{const e=new URL(t);if(!ue.includes(e.protocol)){console.warn("InkWeave: Blocked unsafe URL protocol:",e.protocol);return}}catch{console.warn("InkWeave: Invalid URL:",t);return}window.open(t,"_blank","noopener,noreferrer")}})},me=()=>{r.Patches.add(function(){let t=null;const e=r.choicesStore.subscribe(()=>{t&&clearTimeout(t),t=setTimeout(()=>{const s=document.querySelector('[data-inkweave="choices"] > li:last-child');if(s){const o=document.querySelector('[data-inkweave="story"]');o==null||o.scrollTo({top:s.offsetTop,behavior:"smooth"})}},0)});this.cleanups.push(()=>{e(),t&&clearTimeout(t)})},{})};exports.Image=ce;exports.loadAudio=j;exports.loadAutoButton=k;exports.loadAutosave=G;exports.loadCdButton=te;exports.loadFadeEffect=ne;exports.loadImage=le;exports.loadLinkopen=de;exports.loadMemory=z;exports.loadScrollafterchoice=me;exports.memory=P;exports.useStoryImage=h;
|
|
17
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/memory/storage.ts","../src/memory/index.ts","../src/image/Image.tsx","../src/image/index.ts","../src/audio/AudioController.ts","../src/audio/index.ts","../src/fadeEffect/index.ts","../src/scrollafterchoice/index.ts","../src/linkopen/index.ts","../src/autoButton/AutoButton.tsx","../src/autoButton/index.ts","../src/cdButton/CdButton.tsx","../src/cdButton/index.ts","../src/autosave/index.ts"],"sourcesContent":["import { create } from 'zustand';\nimport { persist, StorageValue } from 'zustand/middleware';\n\nconst StorageType: { [key: string]: Storage } = {\n\tlocal: localStorage,\n\tsession: sessionStorage,\n};\n\nlet type = 'local';\nconst getStorage = () => {\n\treturn StorageType[type];\n};\n\nexport interface SaveSlot {\n\tdata: string;\n\ttimestamp: string;\n\tmeta: string;\n}\n\nexport class Save implements SaveSlot {\n\tdata: string;\n\ttimestamp: string;\n\tmeta: string;\n\n\tconstructor(data: object) {\n\t\tthis.data = JSON.stringify(data);\n\t\tthis.timestamp = new Intl.DateTimeFormat(undefined, {\n\t\t\tmonth: 'short',\n\t\t\tday: 'numeric',\n\t\t\thour: '2-digit',\n\t\t\tminute: '2-digit',\n\t\t}).format(Date.now());\n\t\tthis.meta = 'autogenerated';\n\t}\n}\n\ninterface StorageInterface {\n\tstorage: Map<string, SaveSlot[]>;\n\tsetStorage: (title: string, index: number, data: object) => void;\n\tchangeFormat: (format: string) => void;\n}\n\nconst useStorage = create<StorageInterface>()(\n\tpersist(\n\t\t(set, get) => ({\n\t\t\tstorage: new Map(),\n\t\t\tsetStorage: (title, index, data) => {\n\t\t\t\tconst newSavesMap = new Map(get().storage);\n\t\t\t\tconst file_saves = [...(newSavesMap.get(title) || [])];\n\t\t\t\tfile_saves[index] = new Save(data);\n\t\t\t\tnewSavesMap.set(title, file_saves);\n\t\t\t\tset({ storage: newSavesMap });\n\t\t\t},\n\t\t\tchangeFormat: (format) => {\n\t\t\t\ttype = format;\n\t\t\t},\n\t\t}),\n\t\t{\n\t\t\tname: 'inkStory',\n\t\t\tstorage: {\n\t\t\t\tgetItem: (name) => {\n\t\t\t\t\tconst str = getStorage().getItem(name);\n\t\t\t\t\tif (!str) return null;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst { state } = JSON.parse(str);\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\t\t...state,\n\t\t\t\t\t\t\t\tstorage: new Map(state.storage),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tconsole.error('InkWeave: Failed to parse storage data:', e);\n\t\t\t\t\t\treturn null;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tsetItem: (name, newValue: StorageValue<StorageInterface>) => {\n\t\t\t\t\tconst str = JSON.stringify({\n\t\t\t\t\t\tstate: {\n\t\t\t\t\t\t\t...newValue.state,\n\t\t\t\t\t\t\tstorage: Array.from(\n\t\t\t\t\t\t\t\tnewValue.state.storage.entries()\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t\tgetStorage().setItem(name, str);\n\t\t\t\t},\n\t\t\t\tremoveItem: (name) => {\n\t\t\t\t\tgetStorage().removeItem(name);\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t)\n);\n\nexport default useStorage;","import type { InkStory } from '@inkweave/core';\nimport { Patches } from '@inkweave/core';\nimport useStorage from './storage';\nimport type { SaveSlot } from './storage';\n\ninterface MemorySaveData {\n\tstate: string;\n\t[key: string]: string | number | boolean | string[] | undefined;\n}\n\nlet options = {\n\tmemory_format: 'local',\n};\n\nconst show = (title: string): SaveSlot[] | null => {\n\treturn useStorage((state) => state.storage.get(title) || null);\n};\n\nconst save = (index: number, ink: InkStory) => {\n\tconst saveData: MemorySaveData = {\n\t\tstate: ink.story.state.toJson(),\n\t};\n\tink.save_label.forEach((label) => {\n\t\tconst value = ink[label as keyof InkStory];\n\t\tif (label in ink && value !== undefined) {\n\t\t\tif (\n\t\t\t\ttypeof value === 'string' ||\n\t\t\t\ttypeof value === 'number' ||\n\t\t\t\ttypeof value === 'boolean' ||\n\t\t\t\tArray.isArray(value)\n\t\t\t) {\n\t\t\t\tsaveData[label] = value as string | number | boolean | string[];\n\t\t\t}\n\t\t}\n\t});\n\tuseStorage.getState().setStorage(ink.title, index, saveData);\n};\n\nconst load = (save_data: string, ink: InkStory) => {\n\tlet save: MemorySaveData | null = null;\n\ttry {\n\t\tsave = JSON.parse(save_data);\n\t} catch (e) {\n\t\tconsole.error('InkWeave: Failed to parse save data:', e);\n\t\treturn;\n\t}\n\tif (save) {\n\t\tink.story.state.LoadJson(save.state);\n\t\tink.clear();\n\t\tink.save_label.forEach((label) => {\n\t\t\tif (\n\t\t\t\tlabel in ink &&\n\t\t\t\ttypeof ink[label as keyof InkStory] !== 'undefined' &&\n\t\t\t\tlabel in save\n\t\t\t)\n\t\t\t\t(ink as Record<string, unknown>)[label] = save[label];\n\t\t});\n\t\tink.continue();\n\t}\n};\n\nconst loadMemory = () => {\n\tPatches.add(function () {\n\t\tuseStorage.getState().changeFormat(options.memory_format);\n\t}, options);\n};\n\nexport const memory = { save, load, show };\nexport type { SaveSlot };\nexport default loadMemory;","import { memo, useState, useCallback, useEffect } from 'react';\nimport { useStoryImage } from './index';\n\ninterface ImageProps {\n\tclassName?: string;\n\tfallback?: React.ReactNode;\n}\n\nconst ImageComponent: React.FC<ImageProps> = ({ className = '', fallback = null }) => {\n\tconst image = useStoryImage((state) => state.image);\n\tconst [hasError, setHasError] = useState(false);\n\n\tuseEffect(() => {\n\t\tsetHasError(false);\n\t}, [image]);\n\n\tconst handleError = useCallback(() => {\n\t\tsetHasError(true);\n\t\tconsole.warn(`InkWeave: Failed to load image: ${image}`);\n\t}, [image]);\n\n\tconst handleLoad = useCallback(() => {\n\t\tsetHasError(false);\n\t}, []);\n\n\tif (!image) return null;\n\n\tif (hasError) {\n\t\treturn fallback ? <div id=\"inkweave-image\" className={className}>{fallback}</div> : null;\n\t}\n\n\treturn (\n\t\t<div id=\"inkweave-image\" className={className}>\n\t\t\t<img src={image} alt=\"\" onError={handleError} onLoad={handleLoad} />\n\t\t</div>\n\t);\n};\n\nexport default memo(ImageComponent);","import { create } from 'zustand';\nimport { Tags, Patches, type InkStory, type FileHandler } from '@inkweave/core';\n\ndeclare module '@inkweave/core' {\n\tinterface InkStory {\n\t\timage: string;\n\t}\n}\n\ntype StoryImage = {\n\timage: string;\n\tsetImage: (image: string) => void;\n};\n\nexport const useStoryImage = create<StoryImage>((set) => ({\n\timage: '',\n\tsetImage: (image) => set({ image }),\n}));\n\nconst getPath = (path: string, fileHandler?: FileHandler) => {\n\tif (fileHandler && 'resolveFilename' in fileHandler) {\n\t\treturn (fileHandler as { resolveFilename: (f: string) => string }).resolveFilename(path);\n\t}\n\treturn path;\n};\n\nconst load = () => {\n\tTags.add('image', (val: string | null | undefined, ink: InkStory) => {\n\t\tif (val) {\n\t\t\tuseStoryImage.getState().setImage(getPath(val, ink.options.fileHandler));\n\t\t} else {\n\t\t\tuseStoryImage.getState().setImage('');\n\t\t}\n\t});\n\n\tPatches.add(function () {\n\t\tObject.defineProperty(this, 'image', {\n\t\t\tget() {\n\t\t\t\treturn useStoryImage.getState().image;\n\t\t\t},\n\n\t\t\tset(path: string) {\n\t\t\t\tuseStoryImage.getState().setImage(path);\n\t\t\t},\n\t\t});\n\t\tthis.save_label.push('image');\n\t\tthis.clears.push(() => {\n\t\t\tthis.image = '';\n\t\t});\n\t}, {});\n};\n\nexport default load;\nexport { default as Image } from './Image';","export class AudioController {\n\tprivate static _sound: HTMLAudioElement | null = null;\n\tprivate static _music: HTMLAudioElement | null = null;\n\tprivate static _sound_handler: () => void = () => {};\n\tprivate static _music_handler: () => void = () => {};\n\n\tstatic get sound() {\n\t\treturn this._sound;\n\t}\n\n\tstatic get music() {\n\t\treturn this._music;\n\t}\n\n\tstatic get sound_handler() {\n\t\treturn this._sound_handler;\n\t}\n\n\tstatic get music_handler() {\n\t\treturn this._music_handler;\n\t}\n\n\tstatic set_music(path: string) {\n\t\tthis._music = new Audio(path);\n\t\tthis._music.loop = true;\n\t\tthis._music_handler = () => {\n\t\t\tthis._music?.play();\n\t\t};\n\t\tthis._music.addEventListener('canplaythrough', this._music_handler);\n\t}\n\n\tstatic set_sound(path: string) {\n\t\tthis._sound = new Audio(path);\n\t\tthis._sound_handler = () => {\n\t\t\tthis._sound?.play();\n\t\t};\n\t\tthis._sound.addEventListener('canplaythrough', this._sound_handler);\n\t}\n\n\tstatic cleanupSound() {\n\t\tif (this._sound) {\n\t\t\tthis._sound.pause();\n\t\t\tthis._sound.currentTime = 0;\n\t\t\tthis._sound.removeEventListener(\n\t\t\t\t'canplaythrough',\n\t\t\t\tthis._sound_handler\n\t\t\t);\n\t\t\tthis._sound.src = '';\n\t\t}\n\t\tthis._sound = null;\n\t\tthis._sound_handler = () => {};\n\t}\n\n\tstatic cleanupMusic() {\n\t\tif (this._music) {\n\t\t\tthis._music.pause();\n\t\t\tthis._music.currentTime = 0;\n\t\t\tthis._music.removeEventListener(\n\t\t\t\t'canplaythrough',\n\t\t\t\tthis._music_handler\n\t\t\t);\n\t\t\tthis._music.src = '';\n\t\t}\n\t\tthis._music = null;\n\t\tthis._music_handler = () => {};\n\t}\n}","import { Tags, Patches, type InkStory, type FileHandler } from '@inkweave/core';\nimport { AudioController } from './AudioController';\n\nconst getPath = (path: string, fileHandler?: FileHandler) => {\n\tif (fileHandler && 'resolveFilename' in fileHandler) {\n\t\treturn (fileHandler as { resolveFilename: (f: string) => string }).resolveFilename(path);\n\t}\n\treturn path;\n};\n\nconst load = () => {\n\tTags.add('sound', (val: string | null | undefined, ink: InkStory) => {\n\t\tif (val) {\n\t\t\tAudioController.cleanupSound();\n\t\t\tAudioController.set_sound(getPath(val, ink.options.fileHandler));\n\t\t} else {\n\t\t\tAudioController.cleanupSound();\n\t\t}\n\t});\n\n\tTags.add('music', (val: string | null | undefined, ink: InkStory) => {\n\t\tif (val) {\n\t\t\tAudioController.cleanupMusic();\n\t\t\tAudioController.set_music(getPath(val, ink.options.fileHandler));\n\t\t} else {\n\t\t\tAudioController.cleanupMusic();\n\t\t}\n\t});\n\n\tPatches.add(function () {\n\t\tthis.audio = AudioController;\n\t\tthis.cleanups.push(() => {\n\t\t\tAudioController.cleanupSound();\n\t\t\tAudioController.cleanupMusic();\n\t\t});\n\t}, {});\n};\n\nexport default load;","import { Patches, contentsStore, createSelectors, type InkStoryContext } from '@inkweave/core';\nimport { create } from 'zustand';\n\nconst FADE_CSS = `\n#inkweave-contents div,\n#inkweave-choices {\n opacity: 0;\n animation: inkFadeIn 0.5s forwards;\n animation-delay: var(--delay, 0s);\n}\n@keyframes inkFadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n`;\n\nconst options = {\n\tlinedelay: 0.05,\n};\n\ntype ContentComplete = {\n\tcontentComplete: boolean;\n\tlast_content: string;\n\tsetContentComplete: (contentComplete: boolean) => void;\n\tsetLastContent: (contents: string[]) => void;\n};\n\nconst useContentComplete = create<ContentComplete>((set) => ({\n\tcontentComplete: true,\n\tlast_content: '',\n\tsetContentComplete: (contentComplete) => set({ contentComplete }),\n\tsetLastContent: (contents) => {\n\t\tif (contents.length === 0) {\n\t\t\tset({ last_content: '' });\n\t\t\treturn;\n\t\t}\n\t\tconst last_content = contents[contents.length - 1];\n\t\tset({ last_content });\n\t},\n}));\n\nlet styleElement: HTMLStyleElement | null = null;\n\nconst load = () => {\n\t// Inject CSS only once\n\tif (!styleElement) {\n\t\tstyleElement = document.createElement('style');\n\t\tstyleElement.textContent = FADE_CSS;\n\t\tdocument.head.appendChild(styleElement);\n\t}\n\n\tPatches.add(function (this: InkStoryContext) {\n\t\tconst originalChoose = this.choose as (index: number) => void;\n\t\tconst self = this;\n\t\tthis.choose = function (index: number) {\n\t\t\tif (self.options.linedelay != 0) {\n\t\t\t\tuseContentComplete.getState().setContentComplete(false);\n\t\t\t\tuseContentComplete.getState().setLastContent(self.contents as string[]);\n\t\t\t}\n\t\t\treturn originalChoose.call(self, index);\n\t\t};\n\t\tObject.defineProperty(this, 'visibleLines', {\n\t\t\tget() {\n\t\t\t\tconst last_content = useContentComplete.getState().last_content;\n\t\t\t\treturn (self.contents as string[]).lastIndexOf(last_content);\n\t\t\t},\n\t\t});\n\t\tObject.defineProperty(this, 'choicesCanShow', {\n\t\t\tget() {\n\t\t\t\treturn createSelectors(useContentComplete).use.contentComplete();\n\t\t\t},\n\t\t});\n\n\t\tlet timer: ReturnType<typeof setTimeout> | null = null;\n\t\tconst unsub = contentsStore.subscribe(() => {\n\t\t\tif (self.options.linedelay == 0) return;\n\t\t\tif (timer) clearTimeout(timer);\n\t\t\ttimer = setTimeout(() => {\n\t\t\t\tuseContentComplete.getState().setContentComplete(true);\n\t\t\t}, ((self.contents as string[]).length - (self.visibleLines as number)) * (self.options.linedelay as number) * 1000);\n\t\t});\n\n\t\tthis.cleanups.push(() => {\n\t\t\tunsub();\n\t\t\tif (timer) clearTimeout(timer);\n\t\t});\n\t\tthis.clears.push(() => {\n\t\t\tif (self.options.linedelay != 0)\n\t\t\t\tuseContentComplete.getState().setContentComplete(false);\n\t\t\tuseContentComplete.getState().setLastContent([]);\n\t\t});\n\t}, options);\n};\n\nexport default load;","import { Patches, choicesStore } from '@inkweave/core';\n\nconst load = () => {\n\tPatches.add(function () {\n\t\tlet scrollTimer: ReturnType<typeof setTimeout> | null = null;\n\t\t\n\t\tconst unsub = choicesStore.subscribe(() => {\n\t\t\tif (scrollTimer) clearTimeout(scrollTimer);\n\t\t\t\n\t\t\tscrollTimer = setTimeout(() => {\n\t\t\t\tconst lastButton = document.querySelector(\n\t\t\t\t\t'ul#inkweave-choices > li:last-child'\n\t\t\t\t) as HTMLElement;\n\t\t\t\tif (lastButton) {\n\t\t\t\t\tconst element = document.querySelector(\n\t\t\t\t\t\t'#inkweave-story'\n\t\t\t\t\t) as HTMLElement;\n\t\t\t\t\telement?.scrollTo({\n\t\t\t\t\t\ttop: lastButton.offsetTop,\n\t\t\t\t\t\tbehavior: 'smooth',\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}, 0);\n\t\t});\n\t\t\n\t\tthis.cleanups.push(() => {\n\t\t\tunsub();\n\t\t\tif (scrollTimer) clearTimeout(scrollTimer);\n\t\t});\n\t}, {});\n};\n\nexport default load;","import { Tags } from '@inkweave/core';\n\nconst ALLOWED_PROTOCOLS = ['http:', 'https:'];\n\nconst load = () => {\n\tTags.add('linkopen', (val: string | null | undefined) => {\n\t\tif (val) {\n\t\t\ttry {\n\t\t\t\tconst url = new URL(val);\n\t\t\t\tif (!ALLOWED_PROTOCOLS.includes(url.protocol)) {\n\t\t\t\t\tconsole.warn('InkWeave: Blocked unsafe URL protocol:', url.protocol);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\tconsole.warn('InkWeave: Invalid URL:', val);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\twindow.open(val, '_blank', 'noopener,noreferrer');\n\t\t}\n\t});\n};\n\nexport default load;","import { memo, useEffect, useRef } from 'react';\nimport type { ChoiceComponentProps } from '@inkweave/react';\n\nconst AutoChoice: React.FC<ChoiceComponentProps> = ({\n\tval,\n\tonClick,\n\tclassName = '',\n\tchildren,\n}) => {\n\tconst intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\tconst cd = parseFloat(val || '0');\n\n\tuseEffect(() => {\n\t\tif (cd <= 0) return;\n\n\t\tintervalRef.current = setInterval(() => {\n\t\t\tonClick();\n\t\t}, cd * 1000);\n\n\t\treturn () => {\n\t\t\tif (intervalRef.current) {\n\t\t\t\tclearInterval(intervalRef.current);\n\t\t\t}\n\t\t};\n\t}, [cd, onClick]);\n\n\treturn (\n\t\t<a className={`inkweave-btn ${className}`} style={{ display: 'none' }}>\n\t\t\t{children}\n\t\t</a>\n\t);\n};\n\nexport default memo(AutoChoice);","import { ChoiceParser, Patches } from '@inkweave/core';\nimport { ChoiceComponents } from '@inkweave/react';\nimport AutoChoice from './AutoButton';\n\nconst load = () => {\n\tChoiceParser.add('auto', (new_choice, val) => {\n\t\tnew_choice.type = 'auto';\n\t\tnew_choice.val = val;\n\t});\n\tChoiceComponents.register('auto', AutoChoice);\n\tPatches.add(null, {});\n};\n\nexport default load;","import { memo, useState } from 'react';\nimport type { ChoiceComponentProps } from '@inkweave/react';\n\nconst CooldownChoice: React.FC<ChoiceComponentProps> = ({\n\tval,\n\tonClick,\n\tclassName = '',\n\tchildren,\n}) => {\n\tconst [isDisabled, setIsDisabled] = useState(false);\n\tconst cd = parseFloat(val || '0');\n\n\tconst handleClick = () => {\n\t\tif (isDisabled) return;\n\n\t\tonClick();\n\t\tsetIsDisabled(true);\n\n\t\tsetTimeout(() => {\n\t\t\tsetIsDisabled(false);\n\t\t}, cd * 1000);\n\t};\n\n\treturn (\n\t\t<a\n\t\t\tclassName={`inkweave-btn ${className} ${isDisabled ? 'disabled' : ''}`}\n\t\t\tonClick={handleClick}\n\t\t>\n\t\t\t{children}\n\t\t</a>\n\t);\n};\n\nexport default memo(CooldownChoice);","import { ChoiceParser, Patches } from '@inkweave/core';\nimport { ChoiceComponents } from '@inkweave/react';\nimport CooldownChoice from './CdButton';\n\nconst load = () => {\n\tChoiceParser.add('cd', (new_choice, val) => {\n\t\tnew_choice.type = 'cd';\n\t\tnew_choice.val = val;\n\t});\n\tChoiceComponents.register('cd', CooldownChoice);\n\tPatches.add(null, {});\n};\n\nexport default load;","import type { InkStory } from '@inkweave/core';\nimport { Patches, Tags } from '@inkweave/core';\nimport { memory } from '../memory';\n\nconst options = {\n\tautosave_enabled: true,\n};\n\nconst load = () => {\n\tTags.add('autosave', (_: string | null | undefined, ink: InkStory) => {\n\t\tif (ink.options.autosave_enabled) {\n\t\t\tmemory.save(2, ink);\n\t\t}\n\t});\n\n\tPatches.add(null, options);\n};\n\nexport default load;"],"names":["StorageType","type","getStorage","Save","data","__publicField","useStorage","create","persist","set","get","title","index","newSavesMap","file_saves","format","name","str","state","e","newValue","options","show","save","ink","saveData","label","value","load","save_data","loadMemory","Patches","memory","ImageComponent","className","fallback","image","useStoryImage","hasError","setHasError","useState","useEffect","handleError","useCallback","handleLoad","jsx","Image","memo","getPath","path","fileHandler","Tags","val","AudioController","_a","FADE_CSS","useContentComplete","contentComplete","contents","last_content","styleElement","originalChoose","self","createSelectors","timer","unsub","contentsStore","scrollTimer","choicesStore","lastButton","element","ALLOWED_PROTOCOLS","url","AutoChoice","onClick","children","intervalRef","useRef","cd","ChoiceParser","new_choice","ChoiceComponents","CooldownChoice","isDisabled","setIsDisabled","handleClick","_"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/audio/AudioController.ts","../src/audio/index.ts","../src/autoButton/AutoButton.tsx","../src/autoButton/index.ts","../src/memory/storage.ts","../src/memory/index.ts","../src/autosave/index.ts","../src/cdButton/cooldownState.ts","../src/cdButton/CdButton.tsx","../src/cdButton/index.ts","../src/fadeEffect/index.ts","../src/image/Image.tsx","../src/image/index.ts","../src/linkopen/index.ts","../src/scrollafterchoice/index.ts"],"sourcesContent":["export class AudioController {\n private static _sound: HTMLAudioElement | null = null;\n private static _music: HTMLAudioElement | null = null;\n private static _sound_handler: () => void = () => {};\n private static _music_handler: () => void = () => {};\n\n static get sound() {\n return AudioController._sound;\n }\n\n static get music() {\n return AudioController._music;\n }\n\n static get sound_handler() {\n return AudioController._sound_handler;\n }\n\n static get music_handler() {\n return AudioController._music_handler;\n }\n\n static set_music(path: string) {\n AudioController._music = new Audio(path);\n AudioController._music.loop = true;\n AudioController._music_handler = () => {\n AudioController._music?.play();\n };\n AudioController._music.addEventListener(\"canplaythrough\", AudioController._music_handler);\n }\n\n static set_sound(path: string) {\n AudioController._sound = new Audio(path);\n AudioController._sound_handler = () => {\n AudioController._sound?.play();\n };\n AudioController._sound.addEventListener(\"canplaythrough\", AudioController._sound_handler);\n }\n\n static cleanupSound() {\n if (AudioController._sound) {\n AudioController._sound.pause();\n AudioController._sound.currentTime = 0;\n AudioController._sound.removeEventListener(\"canplaythrough\", AudioController._sound_handler);\n AudioController._sound.src = \"\";\n }\n AudioController._sound = null;\n AudioController._sound_handler = () => {};\n }\n\n static cleanupMusic() {\n if (AudioController._music) {\n AudioController._music.pause();\n AudioController._music.currentTime = 0;\n AudioController._music.removeEventListener(\"canplaythrough\", AudioController._music_handler);\n AudioController._music.src = \"\";\n }\n AudioController._music = null;\n AudioController._music_handler = () => {};\n }\n}\n","import { type FileHandler, type InkStory, Patches, Tags } from \"@inkweave/core\";\nimport { AudioController } from \"./AudioController\";\n\nconst getPath = (path: string, fileHandler?: FileHandler) => {\n if (fileHandler && \"resolveFilename\" in fileHandler) {\n return (fileHandler as { resolveFilename: (f: string) => string }).resolveFilename(path);\n }\n return path;\n};\n\nconst load = () => {\n Tags.add(\"sound\", (val: string | null | undefined, ink: InkStory) => {\n if (val) {\n AudioController.cleanupSound();\n AudioController.set_sound(getPath(val, ink.options.fileHandler));\n } else {\n AudioController.cleanupSound();\n }\n });\n\n Tags.add(\"music\", (val: string | null | undefined, ink: InkStory) => {\n if (val) {\n AudioController.cleanupMusic();\n AudioController.set_music(getPath(val, ink.options.fileHandler));\n } else {\n AudioController.cleanupMusic();\n }\n });\n\n Patches.add(function () {\n this.audio = AudioController;\n this.cleanups.push(() => {\n AudioController.cleanupSound();\n AudioController.cleanupMusic();\n });\n }, {});\n};\n\nexport default load;\n","import type { ChoiceComponentProps } from \"@inkweave/react\";\nimport { choiceStyles } from \"@inkweave/react\";\nimport { memo, useEffect, useRef } from \"react\";\n\nconst AutoChoice: React.FC<ChoiceComponentProps> = ({\n choice,\n onClick,\n className = \"\",\n children,\n}) => {\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const onClickRef = useRef(onClick);\n const cd = parseFloat(choice.val || \"0\");\n\n onClickRef.current = onClick;\n\n useEffect(() => {\n if (cd <= 0) return;\n\n intervalRef.current = setInterval(() => {\n onClickRef.current();\n }, cd * 1000);\n\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n }\n };\n }, [cd]);\n\n const buttonClass = `${choiceStyles.button} ${className}`.trim();\n\n return (\n <a className={buttonClass} style={{ display: \"none\" }}>\n {children}\n </a>\n );\n};\n\nexport default memo(AutoChoice);\n","import { ChoiceParser, Patches } from \"@inkweave/core\";\nimport { ChoiceRegistry } from \"@inkweave/react\";\nimport AutoChoice from \"./AutoButton\";\n\nconst load = () => {\n ChoiceParser.add(\"auto\", (new_choice, val) => {\n new_choice.type = \"auto\";\n new_choice.val = val;\n });\n ChoiceRegistry.register(\"auto\", AutoChoice);\n Patches.add(null, {});\n};\n\nexport default load;\n","import { create } from \"zustand\";\nimport { persist, type StorageValue } from \"zustand/middleware\";\n\nconst StorageType: { [key: string]: Storage } = {\n local: localStorage,\n session: sessionStorage,\n};\n\nlet type = \"local\";\nconst getStorage = () => {\n return StorageType[type];\n};\n\nexport interface SaveSlot {\n data: string;\n timestamp: string;\n meta: string;\n}\n\nexport class Save implements SaveSlot {\n data: string;\n timestamp: string;\n meta: string;\n\n constructor(data: object) {\n this.data = JSON.stringify(data);\n this.timestamp = new Intl.DateTimeFormat(undefined, {\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n }).format(Date.now());\n this.meta = \"autogenerated\";\n }\n}\n\ninterface StorageInterface {\n storage: Map<string, SaveSlot[]>;\n setStorage: (title: string, index: number, data: object) => void;\n changeFormat: (format: string) => void;\n}\n\nconst useStorage = create<StorageInterface>()(\n persist(\n (set, get) => ({\n storage: new Map(),\n setStorage: (title, index, data) => {\n const newSavesMap = new Map(get().storage);\n const file_saves = [...(newSavesMap.get(title) || [])];\n file_saves[index] = new Save(data);\n newSavesMap.set(title, file_saves);\n set({ storage: newSavesMap });\n },\n changeFormat: (format) => {\n type = format;\n },\n }),\n {\n name: \"inkStory\",\n storage: {\n getItem: (name) => {\n const str = getStorage().getItem(name);\n if (!str) return null;\n try {\n const { state } = JSON.parse(str);\n return {\n state: {\n ...state,\n storage: new Map(state.storage),\n },\n };\n } catch (e) {\n console.error(\"InkWeave: Failed to parse storage data:\", e);\n return null;\n }\n },\n setItem: (name, newValue: StorageValue<StorageInterface>) => {\n const str = JSON.stringify({\n state: {\n ...newValue.state,\n storage: Array.from(newValue.state.storage.entries()),\n },\n });\n getStorage().setItem(name, str);\n },\n removeItem: (name) => {\n getStorage().removeItem(name);\n },\n },\n },\n ),\n);\n\nexport default useStorage;\n","import type { InkStory } from \"@inkweave/core\";\nimport { Patches } from \"@inkweave/core\";\nimport type { SaveSlot } from \"./storage\";\nimport useStorage from \"./storage\";\n\ninterface MemorySaveData {\n state: string;\n [key: string]: string | number | boolean | string[] | undefined;\n}\n\nconst options = {\n memory_format: \"local\",\n};\n\nconst show = (title: string): SaveSlot[] | null => {\n return useStorage((state) => state.storage.get(title) || null);\n};\n\nconst save = (index: number, ink: InkStory) => {\n const saveData: MemorySaveData = {\n state: ink.story.state.toJson(),\n };\n ink.save_label.forEach((label) => {\n const value = ink[label as keyof InkStory];\n if (label in ink && value !== undefined) {\n if (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\" ||\n Array.isArray(value)\n ) {\n saveData[label] = value as string | number | boolean | string[];\n }\n }\n });\n useStorage.getState().setStorage(ink.title, index, saveData);\n};\n\nconst load = (save_data: string, ink: InkStory) => {\n let save: MemorySaveData | null = null;\n try {\n save = JSON.parse(save_data);\n } catch (e) {\n console.error(\"InkWeave: Failed to parse save data:\", e);\n return;\n }\n if (save) {\n ink.story.state.LoadJson(save.state);\n ink.clear();\n ink.save_label.forEach((label) => {\n if (label in ink && typeof ink[label as keyof InkStory] !== \"undefined\" && label in save)\n (ink as Record<string, unknown>)[label] = save[label];\n });\n ink.continue();\n }\n};\n\nconst loadMemory = () => {\n Patches.add(() => {\n useStorage.getState().changeFormat(options.memory_format);\n }, options);\n};\n\nexport const memory = { save, load, show };\nexport type { SaveSlot };\nexport default loadMemory;\n","import type { InkStory } from \"@inkweave/core\";\nimport { Patches, Tags } from \"@inkweave/core\";\nimport { memory } from \"../memory\";\n\nconst options = {\n autosave_enabled: true,\n};\n\nconst load = () => {\n Tags.add(\"autosave\", (_: string | null | undefined, ink: InkStory) => {\n if (ink.options.autosave_enabled) {\n memory.save(1, ink);\n }\n });\n\n Patches.add(null, options);\n};\n\nexport default load;\n","// 存储所有 cd 按钮的冷却状态\nconst cooldownStates = new Map<string, number>();\n\nexport function getCooldownKey(choice: { type: string; text: string; val?: string }): string {\n return `${choice.type}_${choice.text}_${choice.val || \"\"}`;\n}\n\nexport function isCooldownActive(key: string): boolean {\n const cooldownUntil = cooldownStates.get(key) || 0;\n return Date.now() < cooldownUntil;\n}\n\nexport function getRemainingSeconds(key: string): number {\n const cooldownUntil = cooldownStates.get(key) || 0;\n const remainingMs = Math.max(0, cooldownUntil - Date.now());\n return Math.ceil(remainingMs / 1000);\n}\n\nexport function setCooldown(key: string, seconds: number): void {\n cooldownStates.set(key, Date.now() + seconds * 1000);\n}\n","import type { ChoiceComponentProps } from \"@inkweave/react\";\nimport { choiceStyles, useStory } from \"@inkweave/react\";\nimport { memo, useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n getCooldownKey,\n getRemainingSeconds,\n isCooldownActive,\n setCooldown,\n} from \"./cooldownState\";\n\nconst CooldownChoice: React.FC<ChoiceComponentProps> = ({\n choice,\n onClick,\n className = \"\",\n children,\n}) => {\n const cd = parseFloat(choice.val || \"0\");\n const key = getCooldownKey(choice);\n const ink = useStory();\n const [, setTick] = useState(0);\n const isMountedRef = useRef(true);\n\n const isDisabled = isCooldownActive(key);\n const remainingSeconds = getRemainingSeconds(key);\n\n useEffect(() => {\n return () => {\n isMountedRef.current = false;\n };\n }, []);\n\n useEffect(() => {\n if (!isDisabled) return;\n const interval = setInterval(() => {\n if (isMountedRef.current) {\n setTick((t) => t + 1);\n }\n }, 1000);\n return () => clearInterval(interval);\n }, [isDisabled]);\n\n const handleClick = useCallback(() => {\n if (isDisabled) return;\n onClick();\n setCooldown(key, cd);\n setTick((t) => t + 1); // 触发重渲染\n }, [isDisabled, cd, onClick, key]);\n\n const buttonClass =\n `${choiceStyles?.button || \"\"} ${className} ${isDisabled ? choiceStyles?.disabled || \"\" : \"\"}`.trim();\n\n const template = (ink.options.cdTemplate as string) || \"{text} ({time})\";\n const displayText =\n isDisabled && remainingSeconds > 0\n ? template.replace(\"{text}\", String(children)).replace(\"{time}\", String(remainingSeconds))\n : children;\n\n return (\n <a className={buttonClass} onClick={handleClick}>\n {displayText}\n </a>\n );\n};\n\nexport default memo(CooldownChoice);\n","import { ChoiceParser, Patches } from \"@inkweave/core\";\nimport { ChoiceRegistry } from \"@inkweave/react\";\nimport CooldownChoice from \"./CdButton\";\n\nconst options = {\n cdTemplate: \"{text} ({time})\",\n};\n\nconst load = () => {\n ChoiceParser.add(\"cd\", (new_choice, val) => {\n new_choice.type = \"cd\";\n new_choice.val = val;\n });\n ChoiceRegistry.register(\"cd\", CooldownChoice);\n Patches.add(null, options);\n};\n\nexport default load;\n","import {\n contentsStore,\n createSelectors,\n type InkStoryContext,\n Patches,\n Tags,\n} from \"@inkweave/core\";\nimport { create } from \"zustand\";\n\nconst options = {\n // 控制文字显示延迟速度(秒),可通过初始化时传入 linedelay 参数修改\n // 或在 Ink 中使用 #linedelay:0.2 动态调整\n linedelay: 0.05,\n};\n\ntype ContentComplete = {\n contentComplete: boolean;\n last_content: string;\n setContentComplete: (contentComplete: boolean) => void;\n setLastContent: (contents: string[]) => void;\n};\n\nconst useContentComplete = create<ContentComplete>((set) => ({\n contentComplete: true,\n last_content: \"\",\n setContentComplete: (contentComplete) => set({ contentComplete }),\n setLastContent: (contents) => {\n if (contents.length === 0) {\n set({ last_content: \"\" });\n return;\n }\n const last_content = contents[contents.length - 1];\n set({ last_content });\n },\n}));\n\nconst load = () => {\n Tags.add(\"linedelay\", (val: string | null | undefined, ink) => {\n if (val != null) {\n const value = parseFloat(val);\n if (!Number.isNaN(value)) {\n ink.options.linedelay = value;\n if (value === 0) {\n useContentComplete.getState().setContentComplete(true);\n }\n }\n }\n });\n\n Patches.add(function (this: InkStoryContext) {\n const originalChoose = this.choose as (index: number) => void;\n const self = this;\n this.choose = (index: number) => {\n if (self.options.linedelay !== 0) {\n useContentComplete.getState().setContentComplete(false);\n useContentComplete.getState().setLastContent(self.contents as string[]);\n }\n return originalChoose.call(self, index);\n };\n Object.defineProperty(this, \"visibleLines\", {\n get() {\n const last_content = useContentComplete.getState().last_content;\n if (!last_content) return -1;\n return (self.contents as string[]).lastIndexOf(last_content);\n },\n });\n Object.defineProperty(this, \"choicesCanShow\", {\n get() {\n return createSelectors(useContentComplete).use.contentComplete();\n },\n });\n\n let timer: ReturnType<typeof setTimeout> | null = null;\n const unsub = contentsStore.subscribe(() => {\n if (timer) clearTimeout(timer);\n if (self.options.linedelay === 0) {\n useContentComplete.getState().setContentComplete(true);\n return;\n }\n timer = setTimeout(\n () => {\n useContentComplete.getState().setContentComplete(true);\n },\n Math.max(\n 0,\n ((self.contents as string[]).length - (self.visibleLines as number)) *\n (self.options.linedelay as number) *\n 1000,\n ),\n );\n });\n\n this.cleanups.push(() => {\n unsub();\n if (timer) clearTimeout(timer);\n });\n this.clears.push(() => {\n if (self.options.linedelay !== 0) useContentComplete.getState().setContentComplete(false);\n useContentComplete.getState().setLastContent([]);\n });\n }, options);\n};\n\nexport default load;\n","import { memo, useCallback, useEffect, useRef, useState } from \"react\";\nimport { useStoryImage } from \"./index\";\nimport styles from \"./styles.module.css\";\n\ninterface ImageProps {\n className?: string;\n fallback?: React.ReactNode;\n}\n\nconst ImageComponent: React.FC<ImageProps> = ({ className = \"\", fallback = null }) => {\n const image = useStoryImage((state) => state.image);\n const [hasError, setHasError] = useState(false);\n\n useEffect(() => {\n setHasError(false);\n }, []);\n\n const imageRef = useRef(image);\n imageRef.current = image;\n\n const handleError = useCallback(() => {\n setHasError(true);\n console.warn(`InkWeave: Failed to load image: ${imageRef.current}`);\n }, []);\n\n const handleLoad = useCallback(() => {\n setHasError(false);\n }, []);\n\n const containerClassName = `${styles.container} ${className}`.trim();\n\n if (!image) return null;\n\n if (hasError) {\n return fallback ? <div className={containerClassName}>{fallback}</div> : null;\n }\n\n return (\n <div className={containerClassName}>\n <img src={image} alt=\"\" onError={handleError} onLoad={handleLoad} />\n </div>\n );\n};\n\nexport default memo(ImageComponent);\n","import { type FileHandler, type InkStory, Patches, Tags } from \"@inkweave/core\";\nimport { create } from \"zustand\";\n\ndeclare module \"@inkweave/core\" {\n interface InkStory {\n image: string;\n }\n}\n\ntype StoryImage = {\n image: string;\n setImage: (image: string) => void;\n};\n\nexport const useStoryImage = create<StoryImage>((set) => ({\n image: \"\",\n setImage: (image) => set({ image }),\n}));\n\nconst getPath = (path: string, fileHandler?: FileHandler) => {\n if (fileHandler && \"resolveFilename\" in fileHandler) {\n return (fileHandler as { resolveFilename: (f: string) => string }).resolveFilename(path);\n }\n return path;\n};\n\nconst load = () => {\n Tags.add(\"image\", (val: string | null | undefined, ink: InkStory) => {\n if (val) {\n useStoryImage.getState().setImage(getPath(val, ink.options.fileHandler));\n } else {\n useStoryImage.getState().setImage(\"\");\n }\n });\n\n Patches.add(function () {\n Object.defineProperty(this, \"image\", {\n get() {\n return useStoryImage.getState().image;\n },\n\n set(path: string) {\n useStoryImage.getState().setImage(path);\n },\n });\n this.save_label.push(\"image\");\n this.clears.push(() => {\n this.image = \"\";\n });\n }, {});\n};\n\nexport default load;\nexport { default as Image } from \"./Image\";\n","import { Tags } from \"@inkweave/core\";\n\nconst ALLOWED_PROTOCOLS = [\"http:\", \"https:\"];\n\nconst load = () => {\n Tags.add(\"linkopen\", (val: string | null | undefined) => {\n if (val) {\n try {\n const url = new URL(val);\n if (!ALLOWED_PROTOCOLS.includes(url.protocol)) {\n console.warn(\"InkWeave: Blocked unsafe URL protocol:\", url.protocol);\n return;\n }\n } catch {\n console.warn(\"InkWeave: Invalid URL:\", val);\n return;\n }\n window.open(val, \"_blank\", \"noopener,noreferrer\");\n }\n });\n};\n\nexport default load;\n","import { choicesStore, Patches } from \"@inkweave/core\";\n\nconst load = () => {\n Patches.add(function () {\n let scrollTimer: ReturnType<typeof setTimeout> | null = null;\n\n const unsub = choicesStore.subscribe(() => {\n if (scrollTimer) clearTimeout(scrollTimer);\n\n scrollTimer = setTimeout(() => {\n const lastButton = document.querySelector(\n '[data-inkweave=\"choices\"] > li:last-child',\n ) as HTMLElement;\n if (lastButton) {\n const element = document.querySelector('[data-inkweave=\"story\"]') as HTMLElement;\n element?.scrollTo({\n top: lastButton.offsetTop,\n behavior: \"smooth\",\n });\n }\n }, 0);\n });\n\n this.cleanups.push(() => {\n unsub();\n if (scrollTimer) clearTimeout(scrollTimer);\n });\n }, {});\n};\n\nexport default load;\n"],"names":["_AudioController","path","_a","AudioController","getPath","fileHandler","load","Tags","val","ink","Patches","AutoChoice","choice","onClick","className","children","intervalRef","useRef","onClickRef","cd","useEffect","buttonClass","choiceStyles","jsx","memo","ChoiceParser","new_choice","ChoiceRegistry","StorageType","type","getStorage","Save","data","useStorage","create","persist","set","get","title","index","newSavesMap","file_saves","format","name","str","state","e","newValue","options","show","save","saveData","label","value","save_data","loadMemory","memory","_","cooldownStates","getCooldownKey","isCooldownActive","key","cooldownUntil","getRemainingSeconds","remainingMs","setCooldown","seconds","CooldownChoice","useStory","setTick","useState","isMountedRef","isDisabled","remainingSeconds","interval","t","handleClick","useCallback","template","displayText","useContentComplete","contentComplete","contents","last_content","originalChoose","self","createSelectors","timer","unsub","contentsStore","ImageComponent","fallback","image","useStoryImage","hasError","setHasError","imageRef","handleError","handleLoad","containerClassName","styles","Image","ALLOWED_PROTOCOLS","url","scrollTimer","choicesStore","lastButton","element"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
export { default as loadMemory, memory } from './memory';
|
|
2
|
-
export type { SaveSlot } from './memory';
|
|
3
|
-
export { default as loadImage, useStoryImage } from './image';
|
|
4
|
-
export { Image } from './image';
|
|
5
1
|
export { default as loadAudio } from './audio';
|
|
6
|
-
export { default as loadFadeEffect } from './fadeEffect';
|
|
7
|
-
export { default as loadScrollafterchoice } from './scrollafterchoice';
|
|
8
|
-
export { default as loadLinkopen } from './linkopen';
|
|
9
2
|
export { default as loadAutoButton } from './autoButton';
|
|
10
|
-
export { default as loadCdButton } from './cdButton';
|
|
11
3
|
export { default as loadAutosave } from './autosave';
|
|
4
|
+
export { default as loadCdButton } from './cdButton';
|
|
5
|
+
export { default as loadFadeEffect } from './fadeEffect';
|
|
6
|
+
export { default as loadImage, Image, useStoryImage } from './image';
|
|
7
|
+
export { default as loadLinkopen } from './linkopen';
|
|
8
|
+
export type { SaveSlot } from './memory';
|
|
9
|
+
export { default as loadMemory, memory } from './memory';
|
|
10
|
+
export { default as loadScrollafterchoice } from './scrollafterchoice';
|