@cruxext/toast 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +178 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +48 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +63 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Maysara Elshewehy (https://github.com/maysara-elshewehy)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
<!-- ╔══════════════════════════════ BEG ══════════════════════════════╗ -->
|
|
2
|
+
|
|
3
|
+
<br>
|
|
4
|
+
<div align="center">
|
|
5
|
+
<p>
|
|
6
|
+
<img src="./assets/img/logo.png" alt="logo" style="" height="60" />
|
|
7
|
+
</p>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<div align="center">
|
|
11
|
+
<img src="https://img.shields.io/badge/v-0.0.1-black"/>
|
|
12
|
+
<a href="https://github.com/cruxext-org"><img src="https://img.shields.io/badge/🔥-@cruxext-black"/></a>
|
|
13
|
+
<br>
|
|
14
|
+
<img src="https://img.shields.io/badge/coverage-100%25-brightgreen" alt="Test Coverage" />
|
|
15
|
+
<img src="https://img.shields.io/github/issues/cruxext-orgz/toast?style=flat" alt="Github Repo Issues" />
|
|
16
|
+
<img src="https://img.shields.io/github/stars/cruxext-orgz/toast?style=social" alt="GitHub Repo stars" />
|
|
17
|
+
</div>
|
|
18
|
+
<br>
|
|
19
|
+
|
|
20
|
+
<!-- ╚═════════════════════════════════════════════════════════════════╝ -->
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
<!-- ╔══════════════════════════════ DOC ══════════════════════════════╗ -->
|
|
25
|
+
|
|
26
|
+
- ## Overview 👀
|
|
27
|
+
|
|
28
|
+
- #### Why ?
|
|
29
|
+
> A lightweight, reactive toast management solution, built for [`@cruxjs`](https://github.com/cruxjs-org) ecosystem.
|
|
30
|
+
|
|
31
|
+
- #### When ?
|
|
32
|
+
> When you need to display brief, non-blocking feedback or notifications to your users.
|
|
33
|
+
|
|
34
|
+
<br>
|
|
35
|
+
<br>
|
|
36
|
+
|
|
37
|
+
- ## Quick Start 🔥
|
|
38
|
+
|
|
39
|
+
> install [`hmm`](https://github.com/minejs-org/hmm) first.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# in your terminal
|
|
43
|
+
hmm i @cruxext/toast
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> </div>
|
|
47
|
+
<br>
|
|
48
|
+
|
|
49
|
+
- ### Setup
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// in your client config at `client.ts` file, add the toast extension.
|
|
53
|
+
import { toastExtension } from `@cruxext/toast`;
|
|
54
|
+
|
|
55
|
+
const config: ClientManagerConfig = {
|
|
56
|
+
...
|
|
57
|
+
|
|
58
|
+
extensions: [
|
|
59
|
+
...
|
|
60
|
+
toastExtension({
|
|
61
|
+
position : 'bottom-right',
|
|
62
|
+
pre : {
|
|
63
|
+
errors : [
|
|
64
|
+
{
|
|
65
|
+
code : 'e001',
|
|
66
|
+
message : 'An error occurred.',
|
|
67
|
+
}
|
|
68
|
+
],
|
|
69
|
+
warnings: [],
|
|
70
|
+
success : [],
|
|
71
|
+
info : [],
|
|
72
|
+
},
|
|
73
|
+
}),
|
|
74
|
+
],
|
|
75
|
+
};
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
- ### Usage
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
import { toast } from '@cruxext/toast';
|
|
82
|
+
|
|
83
|
+
toast().info('Hello World!');
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
<br>
|
|
87
|
+
<br>
|
|
88
|
+
|
|
89
|
+
- ## Documentation 📑
|
|
90
|
+
|
|
91
|
+
- ### URL Parameters
|
|
92
|
+
|
|
93
|
+
> the toast automatically displays messages based on the URL parameters.
|
|
94
|
+
>
|
|
95
|
+
> the parameters are `terror`, `twarning`, `tsuccess`, and `tinfo`.
|
|
96
|
+
|
|
97
|
+
> each parameter value should be a predefined message code.
|
|
98
|
+
>
|
|
99
|
+
> if the code is not found, the toast will not display any message.
|
|
100
|
+
|
|
101
|
+
- ### API ⛓️
|
|
102
|
+
|
|
103
|
+
- #### Main-Functions
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
// Create a toast extension
|
|
107
|
+
export function toastExtension(config?: ToastConfig) : ClientExtension
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
// Get the toast manager instance
|
|
112
|
+
export const toast: () => ToastManager
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
- #### Toast Class Methods
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
show (message: string, options: ToastOptions = {})
|
|
119
|
+
|
|
120
|
+
success (message: string, options?: Omit<ToastOptions, 'type'>)
|
|
121
|
+
error (message: string, options?: Omit<ToastOptions, 'type'>)
|
|
122
|
+
warning (message: string, options?: Omit<ToastOptions, 'type'>)
|
|
123
|
+
info (message: string, options?: Omit<ToastOptions, 'type'>)
|
|
124
|
+
|
|
125
|
+
dismiss (id: string)
|
|
126
|
+
clear ()
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
- #### Types
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
export interface PredefinedMessage {
|
|
133
|
+
code : string;
|
|
134
|
+
message : string;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export interface ToastConfig {
|
|
138
|
+
containerId? : string;
|
|
139
|
+
position? : 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'top-center' | 'bottom-center';
|
|
140
|
+
className? : string;
|
|
141
|
+
pre : {
|
|
142
|
+
errors? : PredefinedMessage[];
|
|
143
|
+
warnings? : PredefinedMessage[];
|
|
144
|
+
info? : PredefinedMessage[];
|
|
145
|
+
success? : PredefinedMessage[];
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
<div align="center"> <img src="./assets/img/line.png" alt="line" style="display: block; margin-top:20px;margin-bottom:20px;width:500px;"/> </div>
|
|
151
|
+
<br>
|
|
152
|
+
|
|
153
|
+
- ### Related 🔗
|
|
154
|
+
|
|
155
|
+
- ##### [@minejs/jsx](https://github.com/minejs-org/jsx)
|
|
156
|
+
- ##### [@minejs/signals](https://github.com/minejs-org/signals)
|
|
157
|
+
|
|
158
|
+
- ##### [@cruxkit/toast](https://github.com/cruxkit-org/toast)
|
|
159
|
+
|
|
160
|
+
- ##### [@cruxjs/client](https://github.com/cruxjs-org/client)
|
|
161
|
+
- ##### [@cruxjs/app](https://github.com/cruxjs-org/app)
|
|
162
|
+
|
|
163
|
+
<!-- ╚═════════════════════════════════════════════════════════════════╝ -->
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
<!-- ╔══════════════════════════════ END ══════════════════════════════╗ -->
|
|
168
|
+
|
|
169
|
+
<br>
|
|
170
|
+
<br>
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
<div align="center">
|
|
175
|
+
<a href="https://github.com/maysara-elshewehy"><img src="https://img.shields.io/badge/by-Maysara-black"/></a>
|
|
176
|
+
</div>
|
|
177
|
+
|
|
178
|
+
<!-- ╚═════════════════════════════════════════════════════════════════╝ -->
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var jsx=require('@minejs/jsx'),signals=require('@minejs/signals'),toast=require('@cruxkit/toast'),jsxRuntime=require('@minejs/jsx/jsx-runtime');var s=signals.signal([]);function m(r){s.update(t=>{let e=t.find(n=>n.id===r);return !e||e.closing?t:t.map(n=>n.id===r?{...n,closing:true}:n)}),setTimeout(()=>{s.update(t=>{let e=t.find(n=>n.id===r);return e?.onClose&&e.onClose(),t.filter(n=>n.id!==r)});},300);}var f=class{constructor(t){this.containerElement=null;this._cleanupTimer=null;this.config={pre:{errors:[],warnings:[],success:[],info:[]},containerId:"cruxkit-toast-container",position:"bottom-right",className:""};this.config={...this.config,...t},signals.effect(()=>{s().length===0?this.checkCleanup():this._cleanupTimer&&(clearTimeout(this._cleanupTimer),this._cleanupTimer=null);}),typeof window<"u"&&setTimeout(()=>this.checkUrlParams(),250);}get toasts(){return s}checkUrlParams(){try{let t=new URLSearchParams(window.location.search),e=t.get("terror");if(e&&this.config.pre.errors){let o=this.config.pre.errors.find(i=>i.code===e)?.message;o?this.error(o):console.warn(`[ToastManager] Unknown error code: ${e}`);}let n=t.get("twarning");if(n&&this.config.pre.warnings){let o=this.config.pre.warnings.find(i=>i.code===n)?.message;o?this.warning(o):console.warn(`[ToastManager] Unknown warning code: ${n}`);}let c=t.get("tsuccess");if(c&&this.config.pre.success){let o=this.config.pre.success.find(i=>i.code===c)?.message;o?this.success(o):console.warn(`[ToastManager] Unknown success code: ${c}`);}let a=t.get("tinfo");if(a&&this.config.pre.info){let o=this.config.pre.info.find(i=>i.code===a)?.message;o?this.info(o):console.warn(`[ToastManager] Unknown info code: ${a}`);}window.history.replaceState({},"",window.location.pathname);}catch(t){console.error("[ToastManager] Error checking URL params",t);}}ensureMounted(){if(typeof window>"u"||(this._cleanupTimer&&(clearTimeout(this._cleanupTimer),this._cleanupTimer=null),this.containerElement&&document.getElementById(this.config.containerId)))return;let t=document.getElementById(this.config.containerId);t||(t=document.createElement("div"),t.id=this.config.containerId,document.body.appendChild(t)),this.containerElement=t,jsx.render(jsxRuntime.jsx(toast.ToastContainer,{...this.config,toasts:s,onDismiss:e=>this.dismiss(e)}),`#${this.config.containerId}`);}checkCleanup(){s().length===0&&(this._cleanupTimer=setTimeout(()=>{s().length===0&&this.containerElement&&(this.containerElement.remove(),this.containerElement=null,this._cleanupTimer=null);},500));}show(t,e={}){this.ensureMounted();let n=Math.random().toString(36).substr(2,9),c=e.type||"info",a=e.duration||3e3,o={id:n,message:t,type:c,duration:a,onClose:e.onClose};return s.update(i=>[...i,o]),a>0&&setTimeout(()=>{this.dismiss(n);},a),n}success(t,e){return this.show(t,{...e,type:"success"})}error(t,e){return this.show(t,{...e,type:"error"})}warning(t,e){return this.show(t,{...e,type:"warning"})}info(t,e){return this.show(t,{...e,type:"info"})}dismiss(t){m(t);}clear(){s.set([]);}};var l,O=()=>l;function _(r){return {name:"ToastExtension",onBoot:t=>{t.cconfig.allowedQueryParams=["terror","tsuccess","twarning","tinfo",...t.cconfig.allowedQueryParams??[]],l=new f(r);}}}exports.ToastManager=f;exports.toast=O;exports.toastExtension=_;//# sourceMappingURL=index.cjs.map
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/mod/state.ts","../src/mod/manager.tsx","../src/index.ts"],"names":["toastsSignal","signal","dismissToast","id","current","toast","t","ToastManager","config","effect","params","terror","message","msg","twarning","tsuccess","tinfo","e","el","render","jsx","ToastContainer","options","type","duration","instance","toastManager","toastExtension","ctx"],"mappings":"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","file":"index.cjs","sourcesContent":["// src/state.ts\r\n//\r\n// Made with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import { signal } from '@minejs/signals';\r\n import { ToastInstance } from '../types';\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ DATA ════════════════════════════════════════╗\r\n\r\n export const toastsSignal = signal<ToastInstance[]>([]);\r\n\r\n export function dismissToast(id: string) {\r\n toastsSignal.update(current => {\r\n const toast = current.find(t => t.id === id);\r\n if (!toast) return current;\r\n\r\n // If already closing, do nothing\r\n if (toast.closing) return current;\r\n\r\n // Mark as closing to trigger exit animation\r\n return current.map(t =>\r\n t.id === id ? { ...t, closing: true } : t\r\n );\r\n });\r\n\r\n // Actual removal after animation\r\n setTimeout(() => {\r\n toastsSignal.update(current => {\r\n const toast = current.find(t => t.id === id);\r\n if (toast?.onClose) {\r\n toast.onClose();\r\n }\r\n return current.filter(t => t.id !== id);\r\n });\r\n }, 300); // Match animation duration\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n","// src/kit/manager.tsx\r\n//\r\n// Made with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import { render } from '@minejs/jsx';\r\n import { effect } from '@minejs/signals';\r\n import { ToastConfig, ToastInstance, ToastOptions } from '../types';\r\n import { toastsSignal, dismissToast } from './state';\r\n import { ToastContainer } from '@cruxkit/toast';\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n export class ToastManager {\r\n private containerElement: HTMLElement | null = null;\r\n private _cleanupTimer: any = null;\r\n private config: Required<ToastConfig> = {\r\n pre : {\r\n errors : [],\r\n warnings : [],\r\n success : [],\r\n info : [],\r\n },\r\n containerId : 'cruxkit-toast-container',\r\n position : 'bottom-right',\r\n className : '',\r\n };\r\n\r\n get toasts() {\r\n return toastsSignal;\r\n }\r\n\r\n constructor(config?: ToastConfig) {\r\n // Set default config values\r\n this.config = {\r\n ...this.config,\r\n ...config,\r\n };\r\n\r\n // Setup reactive cleanup\r\n effect(() => {\r\n const count = toastsSignal().length;\r\n if (count === 0) {\r\n this.checkCleanup();\r\n } else {\r\n if (this._cleanupTimer) {\r\n clearTimeout(this._cleanupTimer);\r\n this._cleanupTimer = null;\r\n }\r\n }\r\n });\r\n\r\n // Check URL parameters on initialization (client-side only check usually)\r\n if (typeof window !== 'undefined') {\r\n setTimeout(() => this.checkUrlParams(), 250);\r\n }\r\n }\r\n\r\n private checkUrlParams() {\r\n try {\r\n const params = new URLSearchParams(window.location.search);\r\n\r\n const terror = params.get('terror');\r\n if (terror && this.config.pre.errors) {\r\n const message = this.config.pre.errors.find(msg => msg.code === terror)?.message;\r\n if (message) {\r\n this.error(message);\r\n } else {\r\n console.warn(`[ToastManager] Unknown error code: ${terror}`);\r\n }\r\n }\r\n\r\n const twarning = params.get('twarning');\r\n if (twarning && this.config.pre.warnings) {\r\n const message = this.config.pre.warnings.find(msg => msg.code === twarning)?.message;\r\n if (message) {\r\n this.warning(message);\r\n } else {\r\n console.warn(`[ToastManager] Unknown warning code: ${twarning}`);\r\n }\r\n }\r\n\r\n const tsuccess = params.get('tsuccess');\r\n if (tsuccess && this.config.pre.success) {\r\n const message = this.config.pre.success.find(msg => msg.code === tsuccess)?.message;\r\n if (message) {\r\n this.success(message);\r\n } else {\r\n console.warn(`[ToastManager] Unknown success code: ${tsuccess}`);\r\n }\r\n }\r\n\r\n const tinfo = params.get('tinfo');\r\n if (tinfo && this.config.pre.info) {\r\n const message = this.config.pre.info.find(msg => msg.code === tinfo)?.message;\r\n if (message) {\r\n this.info(message);\r\n } else {\r\n console.warn(`[ToastManager] Unknown info code: ${tinfo}`);\r\n }\r\n }\r\n\r\n // Optional: Clean URL params?\r\n window.history.replaceState({}, '', window.location.pathname);\r\n } catch (e) {\r\n console.error('[ToastManager] Error checking URL params', e);\r\n }\r\n }\r\n\r\n private ensureMounted() {\r\n if (typeof window === 'undefined') return;\r\n\r\n // If we have a cleanup timer pending, cancel it because we are adding new toasts\r\n if (this._cleanupTimer) {\r\n clearTimeout(this._cleanupTimer);\r\n this._cleanupTimer = null;\r\n }\r\n\r\n if (this.containerElement && document.getElementById(this.config.containerId!)) return;\r\n\r\n // Check if already in DOM (e.g. from SSR or previous instance that wasn't tracked)\r\n let el = document.getElementById(this.config.containerId!);\r\n if (!el) {\r\n el = document.createElement('div');\r\n el.id = this.config.containerId!;\r\n document.body.appendChild(el);\r\n }\r\n this.containerElement = el;\r\n\r\n // Render the container\r\n // We use default props for now.\r\n // If user wants to configure position, they might need a configure method or we pass it here.\r\n // For now, we assume default.\r\n render(\r\n <ToastContainer\r\n {...this.config}\r\n toasts={toastsSignal}\r\n onDismiss={(id) => this.dismiss(id)}\r\n />,\r\n `#${this.config.containerId}`\r\n );\r\n }\r\n\r\n private checkCleanup() {\r\n // \"remove after finish\"\r\n if (toastsSignal().length === 0) {\r\n // Delay cleanup slightly to allow for exit animations if any (though Overlay usually handles its own existence)\r\n // But more importantly, if user spams toasts, we don't want to mount/unmount rapidly.\r\n this._cleanupTimer = setTimeout(() => {\r\n if (toastsSignal().length === 0 && this.containerElement) {\r\n this.containerElement.remove();\r\n this.containerElement = null;\r\n this._cleanupTimer = null;\r\n }\r\n }, 500);\r\n }\r\n }\r\n\r\n show(message: string, options: ToastOptions = {}) {\r\n this.ensureMounted();\r\n\r\n const id = Math.random().toString(36).substr(2, 9);\r\n const type = options.type || 'info';\r\n const duration = options.duration || 3000;\r\n\r\n const instance: ToastInstance = {\r\n id,\r\n message,\r\n type,\r\n duration,\r\n onClose: options.onClose\r\n };\r\n\r\n toastsSignal.update(current => [...current, instance]);\r\n\r\n if (duration > 0) {\r\n setTimeout(() => {\r\n this.dismiss(id);\r\n }, duration);\r\n }\r\n\r\n return id;\r\n }\r\n\r\n success(message: string, options?: Omit<ToastOptions, 'type'>) {\r\n return this.show(message, { ...options, type: 'success' });\r\n }\r\n\r\n error(message: string, options?: Omit<ToastOptions, 'type'>) {\r\n return this.show(message, { ...options, type: 'error' });\r\n }\r\n\r\n warning(message: string, options?: Omit<ToastOptions, 'type'>) {\r\n return this.show(message, { ...options, type: 'warning' });\r\n }\r\n\r\n info(message: string, options?: Omit<ToastOptions, 'type'>) {\r\n return this.show(message, { ...options, type: 'info' });\r\n }\r\n\r\n dismiss(id: string) {\r\n dismissToast(id);\r\n }\r\n\r\n clear() {\r\n toastsSignal.set([]);\r\n }\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n","// src/index.ts\r\n//\r\n// Made with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import { ClientExtension, ExtensionContext } from \"@cruxjs/base\";\r\n import { ToastConfig } from \"./types\";\r\n import { ToastManager } from \"./mod/manager\";\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ INIT ════════════════════════════════════════╗\r\n\r\n let toastManager : ToastManager;\r\n export const toast = () => toastManager;\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n /**\r\n * Create a toast extension\r\n * @param config Toast configuration\r\n * @returns Toast extension\r\n */\r\n export function toastExtension(config?: ToastConfig) : ClientExtension {\r\n return {\r\n name : 'ToastExtension',\r\n\r\n onBoot: (ctx: ExtensionContext) => {\r\n // inject allowed query params\r\n ctx.cconfig.allowedQueryParams = [\r\n 'terror',\r\n 'tsuccess',\r\n 'twarning',\r\n 'tinfo',\r\n ...ctx.cconfig.allowedQueryParams ?? [],\r\n ];\r\n\r\n // create toast manager instance\r\n toastManager = new ToastManager(config);\r\n }\r\n };\r\n };\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ ════ ════════════════════════════════════════╗\r\n\r\n export * from \"./types\";\r\n export * from \"./mod/manager\";\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { ClientExtension } from '@cruxjs/base';
|
|
2
|
+
import * as _minejs_signals from '@minejs/signals';
|
|
3
|
+
import { ToastInstance, ToastOptions } from '@cruxkit/toast';
|
|
4
|
+
export { ToastInstance, ToastOptions, ToastProps, ToastType } from '@cruxkit/toast';
|
|
5
|
+
|
|
6
|
+
interface PredefinedMessage {
|
|
7
|
+
code: string;
|
|
8
|
+
message: string;
|
|
9
|
+
}
|
|
10
|
+
interface ToastConfig {
|
|
11
|
+
containerId?: string;
|
|
12
|
+
position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'top-center' | 'bottom-center';
|
|
13
|
+
className?: string;
|
|
14
|
+
pre: {
|
|
15
|
+
errors?: PredefinedMessage[];
|
|
16
|
+
warnings?: PredefinedMessage[];
|
|
17
|
+
info?: PredefinedMessage[];
|
|
18
|
+
success?: PredefinedMessage[];
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
declare class ToastManager {
|
|
23
|
+
private containerElement;
|
|
24
|
+
private _cleanupTimer;
|
|
25
|
+
private config;
|
|
26
|
+
get toasts(): _minejs_signals.Signal<ToastInstance[]>;
|
|
27
|
+
constructor(config?: ToastConfig);
|
|
28
|
+
private checkUrlParams;
|
|
29
|
+
private ensureMounted;
|
|
30
|
+
private checkCleanup;
|
|
31
|
+
show(message: string, options?: ToastOptions): string;
|
|
32
|
+
success(message: string, options?: Omit<ToastOptions, 'type'>): string;
|
|
33
|
+
error(message: string, options?: Omit<ToastOptions, 'type'>): string;
|
|
34
|
+
warning(message: string, options?: Omit<ToastOptions, 'type'>): string;
|
|
35
|
+
info(message: string, options?: Omit<ToastOptions, 'type'>): string;
|
|
36
|
+
dismiss(id: string): void;
|
|
37
|
+
clear(): void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
declare const toast: () => ToastManager;
|
|
41
|
+
/**
|
|
42
|
+
* Create a toast extension
|
|
43
|
+
* @param config Toast configuration
|
|
44
|
+
* @returns Toast extension
|
|
45
|
+
*/
|
|
46
|
+
declare function toastExtension(config?: ToastConfig): ClientExtension;
|
|
47
|
+
|
|
48
|
+
export { type PredefinedMessage, type ToastConfig, ToastManager, toast, toastExtension };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { ClientExtension } from '@cruxjs/base';
|
|
2
|
+
import * as _minejs_signals from '@minejs/signals';
|
|
3
|
+
import { ToastInstance, ToastOptions } from '@cruxkit/toast';
|
|
4
|
+
export { ToastInstance, ToastOptions, ToastProps, ToastType } from '@cruxkit/toast';
|
|
5
|
+
|
|
6
|
+
interface PredefinedMessage {
|
|
7
|
+
code: string;
|
|
8
|
+
message: string;
|
|
9
|
+
}
|
|
10
|
+
interface ToastConfig {
|
|
11
|
+
containerId?: string;
|
|
12
|
+
position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'top-center' | 'bottom-center';
|
|
13
|
+
className?: string;
|
|
14
|
+
pre: {
|
|
15
|
+
errors?: PredefinedMessage[];
|
|
16
|
+
warnings?: PredefinedMessage[];
|
|
17
|
+
info?: PredefinedMessage[];
|
|
18
|
+
success?: PredefinedMessage[];
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
declare class ToastManager {
|
|
23
|
+
private containerElement;
|
|
24
|
+
private _cleanupTimer;
|
|
25
|
+
private config;
|
|
26
|
+
get toasts(): _minejs_signals.Signal<ToastInstance[]>;
|
|
27
|
+
constructor(config?: ToastConfig);
|
|
28
|
+
private checkUrlParams;
|
|
29
|
+
private ensureMounted;
|
|
30
|
+
private checkCleanup;
|
|
31
|
+
show(message: string, options?: ToastOptions): string;
|
|
32
|
+
success(message: string, options?: Omit<ToastOptions, 'type'>): string;
|
|
33
|
+
error(message: string, options?: Omit<ToastOptions, 'type'>): string;
|
|
34
|
+
warning(message: string, options?: Omit<ToastOptions, 'type'>): string;
|
|
35
|
+
info(message: string, options?: Omit<ToastOptions, 'type'>): string;
|
|
36
|
+
dismiss(id: string): void;
|
|
37
|
+
clear(): void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
declare const toast: () => ToastManager;
|
|
41
|
+
/**
|
|
42
|
+
* Create a toast extension
|
|
43
|
+
* @param config Toast configuration
|
|
44
|
+
* @returns Toast extension
|
|
45
|
+
*/
|
|
46
|
+
declare function toastExtension(config?: ToastConfig): ClientExtension;
|
|
47
|
+
|
|
48
|
+
export { type PredefinedMessage, type ToastConfig, ToastManager, toast, toastExtension };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import {render}from'@minejs/jsx';import {signal,effect}from'@minejs/signals';import {ToastContainer}from'@cruxkit/toast';import {jsx}from'@minejs/jsx/jsx-runtime';var s=signal([]);function m(r){s.update(t=>{let e=t.find(n=>n.id===r);return !e||e.closing?t:t.map(n=>n.id===r?{...n,closing:true}:n)}),setTimeout(()=>{s.update(t=>{let e=t.find(n=>n.id===r);return e?.onClose&&e.onClose(),t.filter(n=>n.id!==r)});},300);}var f=class{constructor(t){this.containerElement=null;this._cleanupTimer=null;this.config={pre:{errors:[],warnings:[],success:[],info:[]},containerId:"cruxkit-toast-container",position:"bottom-right",className:""};this.config={...this.config,...t},effect(()=>{s().length===0?this.checkCleanup():this._cleanupTimer&&(clearTimeout(this._cleanupTimer),this._cleanupTimer=null);}),typeof window<"u"&&setTimeout(()=>this.checkUrlParams(),250);}get toasts(){return s}checkUrlParams(){try{let t=new URLSearchParams(window.location.search),e=t.get("terror");if(e&&this.config.pre.errors){let o=this.config.pre.errors.find(i=>i.code===e)?.message;o?this.error(o):console.warn(`[ToastManager] Unknown error code: ${e}`);}let n=t.get("twarning");if(n&&this.config.pre.warnings){let o=this.config.pre.warnings.find(i=>i.code===n)?.message;o?this.warning(o):console.warn(`[ToastManager] Unknown warning code: ${n}`);}let c=t.get("tsuccess");if(c&&this.config.pre.success){let o=this.config.pre.success.find(i=>i.code===c)?.message;o?this.success(o):console.warn(`[ToastManager] Unknown success code: ${c}`);}let a=t.get("tinfo");if(a&&this.config.pre.info){let o=this.config.pre.info.find(i=>i.code===a)?.message;o?this.info(o):console.warn(`[ToastManager] Unknown info code: ${a}`);}window.history.replaceState({},"",window.location.pathname);}catch(t){console.error("[ToastManager] Error checking URL params",t);}}ensureMounted(){if(typeof window>"u"||(this._cleanupTimer&&(clearTimeout(this._cleanupTimer),this._cleanupTimer=null),this.containerElement&&document.getElementById(this.config.containerId)))return;let t=document.getElementById(this.config.containerId);t||(t=document.createElement("div"),t.id=this.config.containerId,document.body.appendChild(t)),this.containerElement=t,render(jsx(ToastContainer,{...this.config,toasts:s,onDismiss:e=>this.dismiss(e)}),`#${this.config.containerId}`);}checkCleanup(){s().length===0&&(this._cleanupTimer=setTimeout(()=>{s().length===0&&this.containerElement&&(this.containerElement.remove(),this.containerElement=null,this._cleanupTimer=null);},500));}show(t,e={}){this.ensureMounted();let n=Math.random().toString(36).substr(2,9),c=e.type||"info",a=e.duration||3e3,o={id:n,message:t,type:c,duration:a,onClose:e.onClose};return s.update(i=>[...i,o]),a>0&&setTimeout(()=>{this.dismiss(n);},a),n}success(t,e){return this.show(t,{...e,type:"success"})}error(t,e){return this.show(t,{...e,type:"error"})}warning(t,e){return this.show(t,{...e,type:"warning"})}info(t,e){return this.show(t,{...e,type:"info"})}dismiss(t){m(t);}clear(){s.set([]);}};var l,O=()=>l;function _(r){return {name:"ToastExtension",onBoot:t=>{t.cconfig.allowedQueryParams=["terror","tsuccess","twarning","tinfo",...t.cconfig.allowedQueryParams??[]],l=new f(r);}}}export{f as ToastManager,O as toast,_ as toastExtension};//# sourceMappingURL=index.js.map
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/mod/state.ts","../src/mod/manager.tsx","../src/index.ts"],"names":["toastsSignal","signal","dismissToast","id","current","toast","t","ToastManager","config","effect","params","terror","message","msg","twarning","tsuccess","tinfo","e","el","render","jsx","ToastContainer","options","type","duration","instance","toastManager","toastExtension","ctx"],"mappings":"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","file":"index.js","sourcesContent":["// src/state.ts\r\n//\r\n// Made with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import { signal } from '@minejs/signals';\r\n import { ToastInstance } from '../types';\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ DATA ════════════════════════════════════════╗\r\n\r\n export const toastsSignal = signal<ToastInstance[]>([]);\r\n\r\n export function dismissToast(id: string) {\r\n toastsSignal.update(current => {\r\n const toast = current.find(t => t.id === id);\r\n if (!toast) return current;\r\n\r\n // If already closing, do nothing\r\n if (toast.closing) return current;\r\n\r\n // Mark as closing to trigger exit animation\r\n return current.map(t =>\r\n t.id === id ? { ...t, closing: true } : t\r\n );\r\n });\r\n\r\n // Actual removal after animation\r\n setTimeout(() => {\r\n toastsSignal.update(current => {\r\n const toast = current.find(t => t.id === id);\r\n if (toast?.onClose) {\r\n toast.onClose();\r\n }\r\n return current.filter(t => t.id !== id);\r\n });\r\n }, 300); // Match animation duration\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n","// src/kit/manager.tsx\r\n//\r\n// Made with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import { render } from '@minejs/jsx';\r\n import { effect } from '@minejs/signals';\r\n import { ToastConfig, ToastInstance, ToastOptions } from '../types';\r\n import { toastsSignal, dismissToast } from './state';\r\n import { ToastContainer } from '@cruxkit/toast';\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n export class ToastManager {\r\n private containerElement: HTMLElement | null = null;\r\n private _cleanupTimer: any = null;\r\n private config: Required<ToastConfig> = {\r\n pre : {\r\n errors : [],\r\n warnings : [],\r\n success : [],\r\n info : [],\r\n },\r\n containerId : 'cruxkit-toast-container',\r\n position : 'bottom-right',\r\n className : '',\r\n };\r\n\r\n get toasts() {\r\n return toastsSignal;\r\n }\r\n\r\n constructor(config?: ToastConfig) {\r\n // Set default config values\r\n this.config = {\r\n ...this.config,\r\n ...config,\r\n };\r\n\r\n // Setup reactive cleanup\r\n effect(() => {\r\n const count = toastsSignal().length;\r\n if (count === 0) {\r\n this.checkCleanup();\r\n } else {\r\n if (this._cleanupTimer) {\r\n clearTimeout(this._cleanupTimer);\r\n this._cleanupTimer = null;\r\n }\r\n }\r\n });\r\n\r\n // Check URL parameters on initialization (client-side only check usually)\r\n if (typeof window !== 'undefined') {\r\n setTimeout(() => this.checkUrlParams(), 250);\r\n }\r\n }\r\n\r\n private checkUrlParams() {\r\n try {\r\n const params = new URLSearchParams(window.location.search);\r\n\r\n const terror = params.get('terror');\r\n if (terror && this.config.pre.errors) {\r\n const message = this.config.pre.errors.find(msg => msg.code === terror)?.message;\r\n if (message) {\r\n this.error(message);\r\n } else {\r\n console.warn(`[ToastManager] Unknown error code: ${terror}`);\r\n }\r\n }\r\n\r\n const twarning = params.get('twarning');\r\n if (twarning && this.config.pre.warnings) {\r\n const message = this.config.pre.warnings.find(msg => msg.code === twarning)?.message;\r\n if (message) {\r\n this.warning(message);\r\n } else {\r\n console.warn(`[ToastManager] Unknown warning code: ${twarning}`);\r\n }\r\n }\r\n\r\n const tsuccess = params.get('tsuccess');\r\n if (tsuccess && this.config.pre.success) {\r\n const message = this.config.pre.success.find(msg => msg.code === tsuccess)?.message;\r\n if (message) {\r\n this.success(message);\r\n } else {\r\n console.warn(`[ToastManager] Unknown success code: ${tsuccess}`);\r\n }\r\n }\r\n\r\n const tinfo = params.get('tinfo');\r\n if (tinfo && this.config.pre.info) {\r\n const message = this.config.pre.info.find(msg => msg.code === tinfo)?.message;\r\n if (message) {\r\n this.info(message);\r\n } else {\r\n console.warn(`[ToastManager] Unknown info code: ${tinfo}`);\r\n }\r\n }\r\n\r\n // Optional: Clean URL params?\r\n window.history.replaceState({}, '', window.location.pathname);\r\n } catch (e) {\r\n console.error('[ToastManager] Error checking URL params', e);\r\n }\r\n }\r\n\r\n private ensureMounted() {\r\n if (typeof window === 'undefined') return;\r\n\r\n // If we have a cleanup timer pending, cancel it because we are adding new toasts\r\n if (this._cleanupTimer) {\r\n clearTimeout(this._cleanupTimer);\r\n this._cleanupTimer = null;\r\n }\r\n\r\n if (this.containerElement && document.getElementById(this.config.containerId!)) return;\r\n\r\n // Check if already in DOM (e.g. from SSR or previous instance that wasn't tracked)\r\n let el = document.getElementById(this.config.containerId!);\r\n if (!el) {\r\n el = document.createElement('div');\r\n el.id = this.config.containerId!;\r\n document.body.appendChild(el);\r\n }\r\n this.containerElement = el;\r\n\r\n // Render the container\r\n // We use default props for now.\r\n // If user wants to configure position, they might need a configure method or we pass it here.\r\n // For now, we assume default.\r\n render(\r\n <ToastContainer\r\n {...this.config}\r\n toasts={toastsSignal}\r\n onDismiss={(id) => this.dismiss(id)}\r\n />,\r\n `#${this.config.containerId}`\r\n );\r\n }\r\n\r\n private checkCleanup() {\r\n // \"remove after finish\"\r\n if (toastsSignal().length === 0) {\r\n // Delay cleanup slightly to allow for exit animations if any (though Overlay usually handles its own existence)\r\n // But more importantly, if user spams toasts, we don't want to mount/unmount rapidly.\r\n this._cleanupTimer = setTimeout(() => {\r\n if (toastsSignal().length === 0 && this.containerElement) {\r\n this.containerElement.remove();\r\n this.containerElement = null;\r\n this._cleanupTimer = null;\r\n }\r\n }, 500);\r\n }\r\n }\r\n\r\n show(message: string, options: ToastOptions = {}) {\r\n this.ensureMounted();\r\n\r\n const id = Math.random().toString(36).substr(2, 9);\r\n const type = options.type || 'info';\r\n const duration = options.duration || 3000;\r\n\r\n const instance: ToastInstance = {\r\n id,\r\n message,\r\n type,\r\n duration,\r\n onClose: options.onClose\r\n };\r\n\r\n toastsSignal.update(current => [...current, instance]);\r\n\r\n if (duration > 0) {\r\n setTimeout(() => {\r\n this.dismiss(id);\r\n }, duration);\r\n }\r\n\r\n return id;\r\n }\r\n\r\n success(message: string, options?: Omit<ToastOptions, 'type'>) {\r\n return this.show(message, { ...options, type: 'success' });\r\n }\r\n\r\n error(message: string, options?: Omit<ToastOptions, 'type'>) {\r\n return this.show(message, { ...options, type: 'error' });\r\n }\r\n\r\n warning(message: string, options?: Omit<ToastOptions, 'type'>) {\r\n return this.show(message, { ...options, type: 'warning' });\r\n }\r\n\r\n info(message: string, options?: Omit<ToastOptions, 'type'>) {\r\n return this.show(message, { ...options, type: 'info' });\r\n }\r\n\r\n dismiss(id: string) {\r\n dismissToast(id);\r\n }\r\n\r\n clear() {\r\n toastsSignal.set([]);\r\n }\r\n }\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n","// src/index.ts\r\n//\r\n// Made with ❤️ by Maysara.\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ PACK ════════════════════════════════════════╗\r\n\r\n import { ClientExtension, ExtensionContext } from \"@cruxjs/base\";\r\n import { ToastConfig } from \"./types\";\r\n import { ToastManager } from \"./mod/manager\";\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ INIT ════════════════════════════════════════╗\r\n\r\n let toastManager : ToastManager;\r\n export const toast = () => toastManager;\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ CORE ════════════════════════════════════════╗\r\n\r\n /**\r\n * Create a toast extension\r\n * @param config Toast configuration\r\n * @returns Toast extension\r\n */\r\n export function toastExtension(config?: ToastConfig) : ClientExtension {\r\n return {\r\n name : 'ToastExtension',\r\n\r\n onBoot: (ctx: ExtensionContext) => {\r\n // inject allowed query params\r\n ctx.cconfig.allowedQueryParams = [\r\n 'terror',\r\n 'tsuccess',\r\n 'twarning',\r\n 'tinfo',\r\n ...ctx.cconfig.allowedQueryParams ?? [],\r\n ];\r\n\r\n // create toast manager instance\r\n toastManager = new ToastManager(config);\r\n }\r\n };\r\n };\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝\r\n\r\n\r\n\r\n// ╔════════════════════════════════════════ ════ ════════════════════════════════════════╗\r\n\r\n export * from \"./types\";\r\n export * from \"./mod/manager\";\r\n\r\n// ╚══════════════════════════════════════════════════════════════════════════════════════╝"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cruxext/toast",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Lightweight reactive toast manager for CruxJS.",
|
|
5
|
+
"keywords": ["cruxjs", "extension", "toast"],
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"homepage": "https://github.com/cruxext-org/toast#readme",
|
|
8
|
+
"bugs": {
|
|
9
|
+
"url": "https://github.com/cruxext-org/toast/issues"
|
|
10
|
+
},
|
|
11
|
+
"author": {
|
|
12
|
+
"name": "Maysara",
|
|
13
|
+
"email": "maysara.elshewehy@gmail.com",
|
|
14
|
+
"url": "https://github.com/maysara-elshewehy"
|
|
15
|
+
},
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/cruxext-org/toast.git"
|
|
19
|
+
},
|
|
20
|
+
"type": "module",
|
|
21
|
+
"main": "./dist/index.js",
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"files": ["dist"],
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"import": "./dist/index.js",
|
|
28
|
+
"require": "./dist/index.js"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsup",
|
|
33
|
+
"lint": "eslint src --ext .ts",
|
|
34
|
+
"test": "bun test"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"bun": ">=1.3.3"
|
|
38
|
+
},
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"bun": "^1.3.3"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@cruxjs/base": "^0.2.0",
|
|
44
|
+
"@cruxkit/toast": "^0.0.2",
|
|
45
|
+
"@minejs/jsx": "^0.1.8",
|
|
46
|
+
"@minejs/signals": "^0.0.6"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@eslint/js": "^9.39.2",
|
|
50
|
+
"@stylistic/eslint-plugin": "^5.7.1",
|
|
51
|
+
"@types/bun": "^1.3.6",
|
|
52
|
+
"@types/jsdom": "^27.0.0",
|
|
53
|
+
"@types/node": "^20.19.30",
|
|
54
|
+
"@types/react": "^19.2.9",
|
|
55
|
+
"bun-plugin-dts": "^0.3.0",
|
|
56
|
+
"bun-types": "^1.3.6",
|
|
57
|
+
"jsdom": "^27.4.0",
|
|
58
|
+
"ts-node": "^10.9.2",
|
|
59
|
+
"tsup": "^8.5.1",
|
|
60
|
+
"typescript": "^5.9.3",
|
|
61
|
+
"typescript-eslint": "^8.53.1"
|
|
62
|
+
}
|
|
63
|
+
}
|