@versatiles/svelte 2.1.0 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/BBoxMap/BBoxMap.svelte +41 -15
- package/dist/components/BBoxMap/BBoxMap.svelte.d.ts +1 -1
- package/dist/components/BBoxMap/lib/{bbox.d.ts → bbox_drawer.d.ts} +12 -8
- package/dist/components/BBoxMap/lib/{bbox.js → bbox_drawer.js} +29 -28
- package/dist/components/MapEditor/components/Dialog.svelte +5 -2
- package/dist/components/MapEditor/components/Dialog.svelte.d.ts +5 -2
- package/dist/components/MapEditor/components/DialogFile.svelte +5 -2
- package/dist/components/MapEditor/lib/map_layer/symbol.d.ts +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/utils/event_handler.d.ts +25 -0
- package/dist/utils/event_handler.js +50 -0
- package/package.json +1 -1
- package/dist/components/MapEditor/lib/utils/event_handler.d.ts +0 -10
- package/dist/components/MapEditor/lib/utils/event_handler.js +0 -39
@@ -4,40 +4,59 @@
|
|
4
4
|
import { getCountryName } from '../../utils/location.js';
|
5
5
|
import BasicMap from '../BasicMap/BasicMap.svelte';
|
6
6
|
import { isDarkMode } from '../../utils/map_style.js';
|
7
|
-
import type { BBox } from 'geojson';
|
8
7
|
import { loadBBoxes } from './BBoxMap.js';
|
9
|
-
import { BBoxDrawer } from './lib/
|
8
|
+
import { BBoxDrawer, isSameBBox, type BBox } from './lib/bbox_drawer.js';
|
10
9
|
|
11
10
|
let { selectedBBox = $bindable() }: { selectedBBox?: BBox } = $props();
|
11
|
+
|
12
12
|
const startTime = Date.now();
|
13
|
-
let bboxDrawer: BBoxDrawer;
|
13
|
+
let bboxDrawer: BBoxDrawer | undefined;
|
14
14
|
let map: MaplibreMapType | undefined = $state();
|
15
15
|
let bboxes: { key: string; value: BBox }[] | undefined = $state();
|
16
16
|
let mapContainer: HTMLElement;
|
17
|
+
let disableZoomTimeout: ReturnType<typeof setTimeout> | undefined;
|
17
18
|
|
18
19
|
async function onMapInit(_map: MaplibreMapType) {
|
19
20
|
map = _map;
|
20
21
|
mapContainer = map.getContainer();
|
21
22
|
map.setPadding({ top: 42, right: 10, bottom: 15, left: 10 });
|
22
|
-
bboxDrawer = new BBoxDrawer(map!, [-180, -85, 180, 85], isDarkMode(mapContainer) ? '#FFFFFF' : '#000000');
|
23
23
|
bboxes = await loadBBoxes();
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
|
25
|
+
bboxDrawer = new BBoxDrawer(
|
26
|
+
map!,
|
27
|
+
selectedBBox ?? [-180, -85, 180, 85],
|
28
|
+
isDarkMode(mapContainer) ? '#FFFFFF' : '#000000'
|
29
|
+
);
|
30
|
+
|
31
|
+
if (selectedBBox) {
|
32
|
+
zoom();
|
33
|
+
}
|
34
|
+
|
35
|
+
bboxDrawer.on('dragEnd', (bbox) => {
|
36
|
+
disableZoomTemporarily();
|
37
|
+
if (!selectedBBox || !isSameBBox(bbox, selectedBBox)) {
|
38
|
+
selectedBBox = bbox;
|
39
|
+
}
|
40
|
+
});
|
27
41
|
}
|
28
42
|
|
29
|
-
|
30
|
-
if (!
|
43
|
+
$effect(() => {
|
44
|
+
if (!selectedBBox) return;
|
45
|
+
zoom();
|
46
|
+
if (bboxDrawer && selectedBBox) bboxDrawer.bbox = selectedBBox;
|
47
|
+
});
|
31
48
|
|
32
|
-
|
49
|
+
function zoom() {
|
50
|
+
if (!bboxDrawer || !map || !selectedBBox) return;
|
51
|
+
if (disableZoomTimeout) return;
|
33
52
|
|
34
|
-
const transform = map.cameraForBounds(
|
53
|
+
const transform = map.cameraForBounds(selectedBBox) as CameraOptions;
|
35
54
|
if (transform == null) return;
|
36
55
|
transform.zoom = transform.zoom ?? 0 - 0.5;
|
37
56
|
transform.bearing = 0;
|
38
57
|
transform.pitch = 0;
|
39
58
|
|
40
|
-
if (Date.now() - startTime <
|
59
|
+
if (Date.now() - startTime < 3000) {
|
41
60
|
map.jumpTo(transform);
|
42
61
|
} else {
|
43
62
|
map.flyTo({ ...transform, essential: true, speed: 5 });
|
@@ -58,6 +77,11 @@
|
|
58
77
|
}
|
59
78
|
return query;
|
60
79
|
}
|
80
|
+
|
81
|
+
function disableZoomTemporarily() {
|
82
|
+
if (disableZoomTimeout) clearTimeout(disableZoomTimeout);
|
83
|
+
disableZoomTimeout = setTimeout(() => (disableZoomTimeout = undefined), 100);
|
84
|
+
}
|
61
85
|
</script>
|
62
86
|
|
63
87
|
<div class="container">
|
@@ -66,19 +90,21 @@
|
|
66
90
|
<AutoComplete
|
67
91
|
items={bboxes}
|
68
92
|
placeholder="Find country, region or city …"
|
69
|
-
change={(bbox) =>
|
93
|
+
change={(bbox) => (selectedBBox = bbox)}
|
70
94
|
initialInputText={getInitialInputText()}
|
71
95
|
/>
|
72
96
|
</div>
|
73
97
|
{/if}
|
74
|
-
<BasicMap {onMapInit}
|
98
|
+
<BasicMap {onMapInit}></BasicMap>
|
75
99
|
</div>
|
76
100
|
|
77
101
|
<style>
|
78
102
|
.container {
|
103
|
+
position: absolute;
|
79
104
|
width: 100%;
|
80
105
|
height: 100%;
|
81
|
-
|
106
|
+
left: 0;
|
107
|
+
top: 0;
|
82
108
|
min-height: 6em;
|
83
109
|
}
|
84
110
|
.input {
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import type geojson from 'geojson';
|
2
|
-
import
|
3
|
-
import
|
2
|
+
import type maplibregl from 'maplibre-gl';
|
3
|
+
import { EventHandler } from '../../../utils/event_handler.js';
|
4
4
|
export type DragPoint = 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | 'nw' | false;
|
5
5
|
export declare const DragPointMap: Map<DragPoint, {
|
6
6
|
cursor: string;
|
@@ -8,22 +8,26 @@ export declare const DragPointMap: Map<DragPoint, {
|
|
8
8
|
flipV: DragPoint;
|
9
9
|
}>;
|
10
10
|
export type BBox = [number, number, number, number];
|
11
|
-
export declare class BBoxDrawer {
|
11
|
+
export declare class BBoxDrawer extends EventHandler<{
|
12
|
+
drag: BBox;
|
13
|
+
dragEnd: BBox;
|
14
|
+
}> {
|
15
|
+
#private;
|
12
16
|
private sourceId;
|
13
17
|
private dragPoint;
|
14
18
|
private isDragging;
|
15
19
|
private map;
|
16
20
|
private canvas;
|
17
|
-
private
|
18
|
-
|
19
|
-
constructor(map: maplibregl.Map, bbox: BBox, color: string, inverted?: boolean);
|
21
|
+
private insideOut;
|
22
|
+
constructor(map: maplibregl.Map, initialBBox: BBox, color: string, insideOut?: boolean);
|
20
23
|
private updateDragPoint;
|
21
24
|
private getAsFeatureCollection;
|
22
|
-
|
23
|
-
|
25
|
+
set bbox(bbox: BBox);
|
26
|
+
get bbox(): BBox;
|
24
27
|
private redraw;
|
25
28
|
private getAsPixel;
|
26
29
|
private checkDragPointAt;
|
27
30
|
private getCursor;
|
28
31
|
private doDrag;
|
29
32
|
}
|
33
|
+
export declare function isSameBBox(a: geojson.BBox, b: geojson.BBox): boolean;
|
@@ -1,6 +1,4 @@
|
|
1
|
-
import {
|
2
|
-
import maplibregl from 'maplibre-gl';
|
3
|
-
import { getMapStyle } from '../../../utils/map_style.js';
|
1
|
+
import { EventHandler } from '../../../utils/event_handler.js';
|
4
2
|
// prettier-ignore
|
5
3
|
export const DragPointMap = new Map([
|
6
4
|
['n', { cursor: 'ns-resize', flipH: 'n', flipV: 's' }],
|
@@ -14,23 +12,22 @@ export const DragPointMap = new Map([
|
|
14
12
|
[false, { cursor: 'default', flipH: false, flipV: false }],
|
15
13
|
]);
|
16
14
|
const worldBBox = [-180, -85, 180, 85];
|
17
|
-
export class BBoxDrawer {
|
15
|
+
export class BBoxDrawer extends EventHandler {
|
18
16
|
sourceId;
|
19
17
|
dragPoint = false;
|
20
18
|
isDragging = false;
|
21
19
|
map;
|
22
20
|
canvas;
|
23
|
-
|
24
|
-
bbox;
|
25
|
-
constructor(map,
|
26
|
-
|
27
|
-
this
|
21
|
+
insideOut;
|
22
|
+
#bbox;
|
23
|
+
constructor(map, initialBBox, color, insideOut) {
|
24
|
+
super();
|
25
|
+
this.#bbox = [...initialBBox];
|
26
|
+
this.insideOut = insideOut ?? true;
|
28
27
|
this.map = map;
|
29
28
|
this.sourceId = 'bbox_' + Math.random().toString(36).slice(2);
|
30
|
-
|
31
|
-
|
32
|
-
style.sources[this.sourceId] = { type: 'geojson', data: this.getAsFeatureCollection() };
|
33
|
-
style.layers.push({
|
29
|
+
map.addSource(this.sourceId, { type: 'geojson', data: this.getAsFeatureCollection() });
|
30
|
+
map.addLayer({
|
34
31
|
id: 'bbox-line_' + Math.random().toString(36).slice(2),
|
35
32
|
type: 'line',
|
36
33
|
source: this.sourceId,
|
@@ -38,7 +35,7 @@ export class BBoxDrawer {
|
|
38
35
|
layout: { 'line-cap': 'round', 'line-join': 'round' },
|
39
36
|
paint: { 'line-color': color }
|
40
37
|
});
|
41
|
-
|
38
|
+
map.addLayer({
|
42
39
|
id: 'bbox-fill_' + Math.random().toString(36).slice(2),
|
43
40
|
type: 'fill',
|
44
41
|
source: this.sourceId,
|
@@ -46,7 +43,6 @@ export class BBoxDrawer {
|
|
46
43
|
layout: {},
|
47
44
|
paint: { 'fill-color': color, 'fill-opacity': 0.2 }
|
48
45
|
});
|
49
|
-
map.setStyle(style);
|
50
46
|
this.canvas = map.getCanvasContainer();
|
51
47
|
map.on('mousemove', (e) => {
|
52
48
|
if (e.originalEvent.buttons % 2 === 0)
|
@@ -58,6 +54,7 @@ export class BBoxDrawer {
|
|
58
54
|
this.doDrag(e.lngLat);
|
59
55
|
this.redraw();
|
60
56
|
e.preventDefault();
|
57
|
+
this.emit('drag', [...this.#bbox]);
|
61
58
|
});
|
62
59
|
map.on('mousedown', (e) => {
|
63
60
|
if (this.isDragging)
|
@@ -73,6 +70,7 @@ export class BBoxDrawer {
|
|
73
70
|
map.on('mouseup', () => {
|
74
71
|
this.isDragging = false;
|
75
72
|
this.updateDragPoint(false);
|
73
|
+
this.emit('dragEnd', [...this.#bbox]);
|
76
74
|
});
|
77
75
|
}
|
78
76
|
updateDragPoint(dragPoint) {
|
@@ -82,10 +80,10 @@ export class BBoxDrawer {
|
|
82
80
|
this.canvas.style.cursor = this.getCursor(dragPoint);
|
83
81
|
}
|
84
82
|
getAsFeatureCollection() {
|
85
|
-
const ring = getRing(
|
83
|
+
const ring = getRing(this.#bbox);
|
86
84
|
return {
|
87
85
|
type: 'FeatureCollection',
|
88
|
-
features: [this.
|
86
|
+
features: [this.insideOut ? polygon(getRing(worldBBox), ring) : polygon(ring), linestring(ring)]
|
89
87
|
};
|
90
88
|
function getRing(bbox) {
|
91
89
|
const x0 = Math.min(bbox[0], bbox[2]);
|
@@ -102,23 +100,23 @@ export class BBoxDrawer {
|
|
102
100
|
return { type: 'Feature', geometry: { type: 'LineString', coordinates }, properties: {} };
|
103
101
|
}
|
104
102
|
}
|
105
|
-
|
106
|
-
this
|
103
|
+
set bbox(bbox) {
|
104
|
+
if (isSameBBox(this.#bbox, bbox))
|
105
|
+
return;
|
106
|
+
this.#bbox = [...bbox];
|
107
107
|
this.redraw();
|
108
108
|
}
|
109
|
-
|
110
|
-
return
|
109
|
+
get bbox() {
|
110
|
+
return [...this.#bbox];
|
111
111
|
}
|
112
112
|
redraw() {
|
113
113
|
const source = this.map.getSource(this.sourceId);
|
114
|
-
if (!source)
|
114
|
+
if (!source || source.type !== 'geojson')
|
115
115
|
return;
|
116
|
-
|
117
|
-
source.setData(this.getAsFeatureCollection());
|
118
|
-
}
|
116
|
+
source.setData(this.getAsFeatureCollection());
|
119
117
|
}
|
120
118
|
getAsPixel() {
|
121
|
-
const bbox =
|
119
|
+
const bbox = this.#bbox;
|
122
120
|
const p0 = this.map.project([bbox[0], bbox[1]]);
|
123
121
|
const p1 = this.map.project([bbox[2], bbox[3]]);
|
124
122
|
return [Math.min(p0.x, p1.x), Math.min(p0.y, p1.y), Math.max(p0.x, p1.x), Math.max(p0.y, p1.y)];
|
@@ -149,7 +147,7 @@ export class BBoxDrawer {
|
|
149
147
|
return DragPointMap.get(drag)?.cursor ?? 'default';
|
150
148
|
}
|
151
149
|
doDrag(lngLat) {
|
152
|
-
this
|
150
|
+
this.#bbox = ((bbox) => {
|
153
151
|
const x = Math.round(lngLat.lng * 1e3) / 1e3;
|
154
152
|
const y = Math.round(lngLat.lat * 1e3) / 1e3;
|
155
153
|
// prettier-ignore
|
@@ -195,6 +193,9 @@ export class BBoxDrawer {
|
|
195
193
|
this.updateDragPoint(DragPointMap.get(this.dragPoint)?.flipV ?? false);
|
196
194
|
}
|
197
195
|
return bbox;
|
198
|
-
});
|
196
|
+
})(this.#bbox);
|
199
197
|
}
|
200
198
|
}
|
199
|
+
export function isSameBBox(a, b) {
|
200
|
+
return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3];
|
201
|
+
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<script lang="ts">
|
2
2
|
import type { Snippet } from 'svelte';
|
3
|
-
import { EventHandler } from '
|
3
|
+
import { EventHandler } from '../../../utils/event_handler.js';
|
4
4
|
|
5
5
|
let {
|
6
6
|
children = $bindable(),
|
@@ -15,7 +15,10 @@
|
|
15
15
|
} = $props();
|
16
16
|
|
17
17
|
let dialog: HTMLDialogElement | null = null;
|
18
|
-
export const eventHandler = new EventHandler
|
18
|
+
export const eventHandler = new EventHandler<{
|
19
|
+
open: void;
|
20
|
+
close: void;
|
21
|
+
}>();
|
19
22
|
|
20
23
|
export function getNode(): HTMLDialogElement {
|
21
24
|
return dialog!;
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import type { Snippet } from 'svelte';
|
2
|
-
import { EventHandler } from '
|
2
|
+
import { EventHandler } from '../../../utils/event_handler.js';
|
3
3
|
type $$ComponentProps = {
|
4
4
|
children?: Snippet;
|
5
5
|
size?: 'big' | 'fullscreen' | 'small';
|
@@ -7,7 +7,10 @@ type $$ComponentProps = {
|
|
7
7
|
onclose?: () => void;
|
8
8
|
};
|
9
9
|
declare const Dialog: import("svelte").Component<$$ComponentProps, {
|
10
|
-
eventHandler: EventHandler
|
10
|
+
eventHandler: EventHandler<{
|
11
|
+
open: void;
|
12
|
+
close: void;
|
13
|
+
}>;
|
11
14
|
getNode: () => HTMLDialogElement;
|
12
15
|
open: () => void;
|
13
16
|
close: () => void;
|
@@ -1,13 +1,16 @@
|
|
1
1
|
<script lang="ts">
|
2
2
|
import { tick } from 'svelte';
|
3
3
|
import Dialog from './Dialog.svelte';
|
4
|
-
import { EventHandler } from '
|
4
|
+
import { EventHandler } from '../../../utils/event_handler.js';
|
5
5
|
|
6
6
|
type Mode = 'download' | 'new' | null;
|
7
7
|
let mode: Mode = $state(null);
|
8
8
|
let dialog: Dialog | null = null;
|
9
9
|
let input: HTMLInputElement | null = $state(null);
|
10
|
-
let eventHandler = new EventHandler
|
10
|
+
let eventHandler = new EventHandler<{
|
11
|
+
A: void;
|
12
|
+
B: void;
|
13
|
+
}>();
|
11
14
|
|
12
15
|
async function openDialog(newMode: Mode) {
|
13
16
|
if (!dialog) return;
|
@@ -19,8 +19,8 @@ export declare class MapLayerSymbol extends MapLayer<LayerSymbol> {
|
|
19
19
|
label: Writable<string>;
|
20
20
|
labelAlign: Writable<number>;
|
21
21
|
symbolInfo: import("svelte/store").Readable<import("../symbols.js").SymbolInfo>;
|
22
|
-
textAnchor: import("svelte/store").Readable<"center" | "
|
23
|
-
textVariableAnchor: import("svelte/store").Readable<("center" | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "
|
22
|
+
textAnchor: import("svelte/store").Readable<"center" | "left" | "right" | "top" | "bottom" | undefined>;
|
23
|
+
textVariableAnchor: import("svelte/store").Readable<("center" | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "left" | "right" | "top" | "bottom")[] | undefined>;
|
24
24
|
constructor(manager: GeometryManager, id: string, source: string);
|
25
25
|
getState(): StateStyle | undefined;
|
26
26
|
setState(state: StateStyle): void;
|
package/dist/index.d.ts
CHANGED
@@ -3,3 +3,4 @@ import BBoxMap from './components/BBoxMap/BBoxMap.svelte';
|
|
3
3
|
import LocatorMap from './components/LocatorMap/LocatorMap.svelte';
|
4
4
|
import MapEditor from './components/MapEditor/MapEditor.svelte';
|
5
5
|
export { BasicMap, BBoxMap, LocatorMap, MapEditor };
|
6
|
+
export { type BBox } from './components/BBoxMap/lib/bbox_drawer.js';
|
package/dist/index.js
CHANGED
@@ -3,3 +3,4 @@ import BBoxMap from './components/BBoxMap/BBoxMap.svelte';
|
|
3
3
|
import LocatorMap from './components/LocatorMap/LocatorMap.svelte';
|
4
4
|
import MapEditor from './components/MapEditor/MapEditor.svelte';
|
5
5
|
export { BasicMap, BBoxMap, LocatorMap, MapEditor };
|
6
|
+
export {} from './components/BBoxMap/lib/bbox_drawer.js';
|
@@ -0,0 +1,25 @@
|
|
1
|
+
/**
|
2
|
+
* Callback type that accepts a payload only if the event actually carries data.
|
3
|
+
* For data‑less events (`void` or `undefined`), the callback takes no argument.
|
4
|
+
*/
|
5
|
+
type EventCallback<T> = T extends void | undefined ? () => void : (data: T) => void;
|
6
|
+
export declare class EventHandler<Events extends Record<string, unknown> = {}> {
|
7
|
+
/** monotonically increasing id for every registered callback */
|
8
|
+
private index;
|
9
|
+
/**
|
10
|
+
* Per‑event registry that keeps the correct data type for every callback
|
11
|
+
* (`drag` maps to `{x: number; y: number}`, `dragEnd` to the same, etc.).
|
12
|
+
*/
|
13
|
+
private events;
|
14
|
+
/** Emit an event (with data only if the event defines some) */
|
15
|
+
emit<K extends keyof Events>(name: K, ...args: Events[K] extends void | undefined ? [] : [data: Events[K]]): void;
|
16
|
+
/** Register a new listener; returns its numeric id so it can be removed later */
|
17
|
+
on<K extends keyof Events>(name: K, callback: EventCallback<Events[K]>): number;
|
18
|
+
/** Register a listener that will fire exactly once */
|
19
|
+
once<K extends keyof Events>(name: K, callback: EventCallback<Events[K]>): number;
|
20
|
+
/** Remove a single listener by id, or all listeners for an event */
|
21
|
+
off<K extends keyof Events>(name: K, id?: number): void;
|
22
|
+
/** Clear the entire registry */
|
23
|
+
clear(): void;
|
24
|
+
}
|
25
|
+
export {};
|
@@ -0,0 +1,50 @@
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
2
|
+
export class EventHandler {
|
3
|
+
/** monotonically increasing id for every registered callback */
|
4
|
+
index = 0;
|
5
|
+
/**
|
6
|
+
* Per‑event registry that keeps the correct data type for every callback
|
7
|
+
* (`drag` maps to `{x: number; y: number}`, `dragEnd` to the same, etc.).
|
8
|
+
*/
|
9
|
+
events = {};
|
10
|
+
/** Emit an event (with data only if the event defines some) */
|
11
|
+
emit(name, ...args) {
|
12
|
+
const payload = args[0];
|
13
|
+
this.events[name]?.forEach((cb) => cb(payload));
|
14
|
+
}
|
15
|
+
/** Register a new listener; returns its numeric id so it can be removed later */
|
16
|
+
on(name, callback) {
|
17
|
+
if (!callback)
|
18
|
+
throw new Error('Callback is required');
|
19
|
+
const bucket = (this.events[name] ??= new Map());
|
20
|
+
const id = ++this.index;
|
21
|
+
bucket.set(id, callback);
|
22
|
+
return id;
|
23
|
+
}
|
24
|
+
/** Register a listener that will fire exactly once */
|
25
|
+
once(name, callback) {
|
26
|
+
const id = this.on(name, ((data) => {
|
27
|
+
this.off(name, id);
|
28
|
+
callback(data);
|
29
|
+
}));
|
30
|
+
return id;
|
31
|
+
}
|
32
|
+
/** Remove a single listener by id, or all listeners for an event */
|
33
|
+
off(name, id) {
|
34
|
+
const bucket = this.events[name];
|
35
|
+
if (!bucket)
|
36
|
+
return;
|
37
|
+
if (id !== undefined) {
|
38
|
+
bucket.delete(id);
|
39
|
+
}
|
40
|
+
else {
|
41
|
+
delete this.events[name];
|
42
|
+
}
|
43
|
+
}
|
44
|
+
/** Clear the entire registry */
|
45
|
+
clear() {
|
46
|
+
for (const key in this.events) {
|
47
|
+
delete this.events[key];
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}
|
package/package.json
CHANGED
@@ -1,10 +0,0 @@
|
|
1
|
-
export declare class EventHandler {
|
2
|
-
private index;
|
3
|
-
private events;
|
4
|
-
constructor();
|
5
|
-
emit(event: string): void;
|
6
|
-
on(name: string, callback: () => void): number;
|
7
|
-
once(name: string, callback: () => void): number;
|
8
|
-
off(name: string, index?: number): void;
|
9
|
-
clear(): void;
|
10
|
-
}
|
@@ -1,39 +0,0 @@
|
|
1
|
-
export class EventHandler {
|
2
|
-
index = 0;
|
3
|
-
events = new Map();
|
4
|
-
constructor() { }
|
5
|
-
emit(event) {
|
6
|
-
this.events.get(event)?.forEach((callback) => callback());
|
7
|
-
}
|
8
|
-
on(name, callback) {
|
9
|
-
if (!callback)
|
10
|
-
throw new Error('Callback is required');
|
11
|
-
if (!this.events.has(name))
|
12
|
-
this.events.set(name, new Map());
|
13
|
-
this.index++;
|
14
|
-
this.events.get(name).set(this.index, callback);
|
15
|
-
return this.index;
|
16
|
-
}
|
17
|
-
once(name, callback) {
|
18
|
-
if (!callback)
|
19
|
-
throw new Error('Callback is required');
|
20
|
-
const index = this.on(name, () => {
|
21
|
-
this.off(name, index);
|
22
|
-
callback();
|
23
|
-
});
|
24
|
-
return index;
|
25
|
-
}
|
26
|
-
off(name, index) {
|
27
|
-
if (!this.events.has(name))
|
28
|
-
return;
|
29
|
-
if (index) {
|
30
|
-
this.events.get(name)?.delete(index);
|
31
|
-
}
|
32
|
-
else {
|
33
|
-
this.events.delete(name);
|
34
|
-
}
|
35
|
-
}
|
36
|
-
clear() {
|
37
|
-
this.events.clear();
|
38
|
-
}
|
39
|
-
}
|