@gesslar/toolkit 1.0.4 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gesslar/toolkit",
3
- "version": "1.0.4",
3
+ "version": "1.3.0",
4
4
  "description": "Get in, bitches, we're going toolkitting.",
5
5
  "main": "./src/index.js",
6
6
  "type": "module",
@@ -3,7 +3,11 @@
3
3
 
4
4
  export {default as Collection} from "./lib/Collection.js"
5
5
  export {default as Data} from "./lib/Data.js"
6
+ export {default as Disposable} from "./lib/Disposable.js"
7
+ export {Disposable as DisposableClass} from "./lib/Disposable.js"
6
8
  export {default as HTML} from "./lib/HTML.js"
9
+ export {HTML as HTMLClass} from "./lib/HTML.js"
10
+ export {default as Notify} from "./lib/Notify.js"
7
11
  export {default as Sass} from "./lib/Sass.js"
8
12
  export {default as Tantrum} from "./lib/Tantrum.js"
9
13
  export {default as Type} from "./lib/TypeSpec.js"
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Simple lifecycle helper that tracks disposer callbacks.
3
+ * Register any teardown functions and call dispose() to run them in reverse.
4
+ */
5
+ export class Disposable {
6
+ #disposers = []
7
+ #disposed = false
8
+
9
+ /**
10
+ * Registers a disposer callback to be executed when disposed.
11
+ *
12
+ * @param {() => void} disposer - Cleanup callback.
13
+ * @returns {() => void} Function to unregister the disposer.
14
+ */
15
+ registerDisposer(disposer) {
16
+ if(this.#disposed || typeof disposer !== "function")
17
+ return () => {}
18
+
19
+ this.#disposers.push(disposer)
20
+
21
+ return () => this.#removeDisposer(disposer)
22
+ }
23
+
24
+ /**
25
+ * Runs all registered disposers in reverse order.
26
+ *
27
+ * @returns {void}
28
+ */
29
+ dispose() {
30
+ if(this.#disposed)
31
+ return
32
+
33
+ this.#disposed = true
34
+
35
+ const errors = []
36
+ this.#disposers.toReversed().forEach(disposer => {
37
+ try {
38
+ disposer()
39
+ } catch(error) {
40
+ errors.push(error)
41
+ }
42
+ })
43
+ this.#disposers.length = 0
44
+
45
+ if(errors.length > 0)
46
+ throw new AggregateError(errors, "Errors occurred during disposal.")
47
+ }
48
+
49
+ /**
50
+ * Whether disposal has run.
51
+ *
52
+ * @returns {boolean} True when dispose() has already been called.
53
+ */
54
+ get disposed() {
55
+ return this.#disposed
56
+ }
57
+
58
+ /**
59
+ * Read-only list of registered disposers.
60
+ *
61
+ * @returns {Array<() => void>} Snapshot of disposer callbacks.
62
+ */
63
+ get disposers() {
64
+ return Object.freeze([...this.#disposers])
65
+ }
66
+
67
+ #removeDisposer(disposer) {
68
+ const index = this.#disposers.indexOf(disposer)
69
+
70
+ if(index >= 0)
71
+ this.#disposers.splice(index, 1)
72
+ }
73
+ }
74
+
75
+ export default new Disposable()
@@ -1,7 +1,7 @@
1
1
  import DOMPurify from "./vendor/dompurify.esm.js"
2
2
  import Sass from "./Sass.js"
3
3
 
4
- export default class HTML {
4
+ export class HTML {
5
5
  #domPurify
6
6
 
7
7
  /**
@@ -135,3 +135,5 @@ export default class HTML {
135
135
  throw Sass.new("DOMPurify sanitization is unavailable in this environment.")
136
136
  }
137
137
  }
138
+
139
+ export default new HTML()
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Thin wrapper around `window` event handling to centralize emit/on/off
3
+ * helpers. Used to dispatch simple CustomEvents and manage listeners in one
4
+ * place.
5
+ */
6
+
7
+ /**
8
+ * @typedef {object} NotifyEventOptions
9
+ * @property {boolean} [bubbles] - Whether the event bubbles up the DOM tree.
10
+ * @property {boolean} [cancelable] - Whether the event can be canceled.
11
+ * @property {boolean} [composed] - Whether the event can cross the shadow DOM boundary.
12
+ */
13
+ export default new class Notify {
14
+ /** @type {string} Display name for debugging. */
15
+ name = "Notify"
16
+
17
+ /**
18
+ * Emits a CustomEvent without expecting a return value.
19
+ *
20
+ * @param {string} type - Event name to dispatch.
21
+ * @param {unknown} [payload] - Value assigned to `event.detail`.
22
+ * @param {boolean | NotifyEventOptions} [options] - CustomEvent options or boolean to set `bubbles`.
23
+ * @returns {void}
24
+ */
25
+ emit(type, payload=undefined, options=undefined) {
26
+ const evt = new CustomEvent(type, this.#buildEventInit(payload, options))
27
+ window.dispatchEvent(evt)
28
+ }
29
+
30
+ /**
31
+ * Emits a CustomEvent and returns the detail for simple request/response flows.
32
+ *
33
+ * @param {string} type - Event name to dispatch.
34
+ * @param {unknown} [payload] - Value assigned to `event.detail`.
35
+ * @param {boolean | NotifyEventOptions} [options] - CustomEvent options or boolean to set `bubbles`.
36
+ * @returns {unknown} The detail placed on the CustomEvent.
37
+ */
38
+ request(type, payload={}, options=undefined) {
39
+ const evt = new CustomEvent(type, this.#buildEventInit(payload, options))
40
+ window.dispatchEvent(evt)
41
+
42
+ return evt.detail
43
+ }
44
+
45
+ /**
46
+ * Registers a listener for the given event type on an HTMLElement (or
47
+ * window, if not specified).
48
+ *
49
+ * @param {string} type - Event name to listen for.
50
+ * @param {(evt: Notify) => void} handler - Listener callback.
51
+ * @param {HTMLElement | Window} [element] - The object to which to attach the handler. Default is window.
52
+ * @param {boolean | object} [options] - Options to pass to addEventListener.
53
+ * @returns {() => void} Dispose function to unregister the handler.
54
+ */
55
+ on(type, handler, element=window, options=undefined) {
56
+ if(!(typeof type === "string" && type))
57
+ throw new Error("No event 'type' specified to listen for.")
58
+
59
+ if(typeof handler !== "function")
60
+ throw new Error("No handler function specified.")
61
+
62
+ element.addEventListener(type, handler, options)
63
+
64
+ return () => this.off(type, handler, element, options)
65
+ }
66
+
67
+ /**
68
+ * Removes a previously registered listener for the given event type.
69
+ *
70
+ * @param {string} type - Event name to remove.
71
+ * @param {(evt: Notify) => void} handler - Listener callback to detach.
72
+ * @param {HTMLElement | Window} [element] - The object from which to remove the handler. Default is window.
73
+ * @param {boolean | object} [options] - Options to pass to removeEventListener.
74
+ * @returns {void}
75
+ */
76
+ off(type, handler, element=window, options=undefined) {
77
+ element.removeEventListener(type, handler, options)
78
+ }
79
+
80
+ #buildEventInit(detail, options) {
81
+ if(typeof options === "boolean")
82
+ return {detail, bubbles: options}
83
+
84
+ if(typeof options === "object" && options !== null)
85
+ return {detail, ...options}
86
+
87
+ return {detail}
88
+ }
89
+ }
package/src/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  // Browser-compatible utilities (pure JS)
2
2
  export {default as Collection} from "./browser/lib/Collection.js"
3
3
  export {default as Data} from "./browser/lib/Data.js"
4
+ export {default as Disposable} from "./browser/lib/Disposable.js"
5
+ export {Disposable as DisposableClass} from "./browser/lib/Disposable.js"
4
6
  export {default as Type} from "./browser/lib/TypeSpec.js"
5
7
  export {default as Valid} from "./lib/Valid.js"
6
8
 
@@ -1,9 +1,11 @@
1
1
  export { default as Collection } from "./lib/Collection.js";
2
2
  export { default as Data } from "./lib/Data.js";
3
- export { default as HTML } from "./lib/HTML.js";
3
+ export { default as Notify } from "./lib/Notify.js";
4
4
  export { default as Sass } from "./lib/Sass.js";
5
5
  export { default as Tantrum } from "./lib/Tantrum.js";
6
6
  export { default as Type } from "./lib/TypeSpec.js";
7
7
  export { default as Util } from "./lib/Util.js";
8
8
  export { default as Valid } from "./lib/Valid.js";
9
+ export { default as Disposable, Disposable as DisposableClass } from "./lib/Disposable.js";
10
+ export { default as HTML, HTML as HTMLClass } from "./lib/HTML.js";
9
11
  //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Simple lifecycle helper that tracks disposer callbacks.
3
+ * Register any teardown functions and call dispose() to run them in reverse.
4
+ */
5
+ export class Disposable {
6
+ /**
7
+ * Registers a disposer callback to be executed when disposed.
8
+ *
9
+ * @param {() => void} disposer - Cleanup callback.
10
+ * @returns {() => void} Function to unregister the disposer.
11
+ */
12
+ registerDisposer(disposer: () => void): () => void;
13
+ /**
14
+ * Runs all registered disposers in reverse order.
15
+ *
16
+ * @returns {void}
17
+ */
18
+ dispose(): void;
19
+ /**
20
+ * Whether disposal has run.
21
+ *
22
+ * @returns {boolean} True when dispose() has already been called.
23
+ */
24
+ get disposed(): boolean;
25
+ /**
26
+ * Read-only list of registered disposers.
27
+ *
28
+ * @returns {Array<() => void>} Snapshot of disposer callbacks.
29
+ */
30
+ get disposers(): Array<() => void>;
31
+ #private;
32
+ }
33
+ declare const _default: Disposable;
34
+ export default _default;
35
+ //# sourceMappingURL=Disposable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Disposable.d.ts","sourceRoot":"","sources":["../../../browser/lib/Disposable.js"],"names":[],"mappings":"AAAA;;;GAGG;AACH;IAIE;;;;;OAKG;IACH,2BAHW,MAAM,IAAI,GACR,MAAM,IAAI,CAStB;IAED;;;;OAIG;IACH,WAFa,IAAI,CAoBhB;IAED;;;;OAIG;IACH,gBAFa,OAAO,CAInB;IAED;;;;OAIG;IACH,iBAFa,KAAK,CAAC,MAAM,IAAI,CAAC,CAI7B;;CAQF"}
@@ -1,4 +1,4 @@
1
- export default class HTML {
1
+ export class HTML {
2
2
  /**
3
3
  * Lightweight HTML helper utilities for browser contexts.
4
4
  *
@@ -35,4 +35,6 @@ export default class HTML {
35
35
  clearHTMLContent(element: Element): void;
36
36
  #private;
37
37
  }
38
+ declare const _default: HTML;
39
+ export default _default;
38
40
  //# sourceMappingURL=HTML.d.ts.map
@@ -0,0 +1,60 @@
1
+ declare const _default: {
2
+ /** @type {string} Display name for debugging. */
3
+ name: string;
4
+ /**
5
+ * Emits a CustomEvent without expecting a return value.
6
+ *
7
+ * @param {string} type - Event name to dispatch.
8
+ * @param {unknown} [payload] - Value assigned to `event.detail`.
9
+ * @param {boolean | NotifyEventOptions} [options] - CustomEvent options or boolean to set `bubbles`.
10
+ * @returns {void}
11
+ */
12
+ emit(type: string, payload?: unknown, options?: boolean | NotifyEventOptions): void;
13
+ /**
14
+ * Emits a CustomEvent and returns the detail for simple request/response flows.
15
+ *
16
+ * @param {string} type - Event name to dispatch.
17
+ * @param {unknown} [payload] - Value assigned to `event.detail`.
18
+ * @param {boolean | NotifyEventOptions} [options] - CustomEvent options or boolean to set `bubbles`.
19
+ * @returns {unknown} The detail placed on the CustomEvent.
20
+ */
21
+ request(type: string, payload?: unknown, options?: boolean | NotifyEventOptions): unknown;
22
+ /**
23
+ * Registers a listener for the given event type on an HTMLElement (or
24
+ * window, if not specified).
25
+ *
26
+ * @param {string} type - Event name to listen for.
27
+ * @param {(evt: Notify) => void} handler - Listener callback.
28
+ * @param {HTMLElement | Window} [element] - The object to which to attach the handler. Default is window.
29
+ * @param {boolean | object} [options] - Options to pass to addEventListener.
30
+ * @returns {() => void} Dispose function to unregister the handler.
31
+ */
32
+ on(type: string, handler: (evt: /*elided*/ any) => void, element?: HTMLElement | Window, options?: boolean | object): () => void;
33
+ /**
34
+ * Removes a previously registered listener for the given event type.
35
+ *
36
+ * @param {string} type - Event name to remove.
37
+ * @param {(evt: Notify) => void} handler - Listener callback to detach.
38
+ * @param {HTMLElement | Window} [element] - The object from which to remove the handler. Default is window.
39
+ * @param {boolean | object} [options] - Options to pass to removeEventListener.
40
+ * @returns {void}
41
+ */
42
+ off(type: string, handler: (evt: /*elided*/ any) => void, element?: HTMLElement | Window, options?: boolean | object): void;
43
+ "__#private@#buildEventInit"(detail: any, options: any): any;
44
+ };
45
+ export default _default;
46
+ export type NotifyEventOptions = {
47
+ /**
48
+ * - Whether the event bubbles up the DOM tree.
49
+ */
50
+ bubbles?: boolean;
51
+ /**
52
+ * - Whether the event can be canceled.
53
+ */
54
+ cancelable?: boolean;
55
+ /**
56
+ * - Whether the event can cross the shadow DOM boundary.
57
+ */
58
+ composed?: boolean;
59
+ };
60
+ //# sourceMappingURL=Notify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Notify.d.ts","sourceRoot":"","sources":["../../../browser/lib/Notify.js"],"names":[],"mappings":";IAaE,iDAAiD;UAAtC,MAAM;IAGjB;;;;;;;OAOG;eAJQ,MAAM,YACN,OAAO,YACP,OAAO,GAAG,kBAAkB,GAC1B,IAAI;IAOjB;;;;;;;OAOG;kBAJQ,MAAM,YACN,OAAO,YACP,OAAO,GAAG,kBAAkB,GAC1B,OAAO;IASpB;;;;;;;;;OASG;aALQ,MAAM,WACN,CAAC,GAAG,gBAAQ,KAAK,IAAI,YACrB,WAAW,GAAG,MAAM,YACpB,OAAO,GAAG,MAAM,GACd,MAAM,IAAI;IAcvB;;;;;;;;OAQG;cALQ,MAAM,WACN,CAAC,GAAG,gBAAQ,KAAK,IAAI,YACrB,WAAW,GAAG,MAAM,YACpB,OAAO,GAAG,MAAM,GACd,IAAI;;;;;;;;cAjEL,OAAO;;;;iBACP,OAAO;;;;eACP,OAAO"}
@@ -14,4 +14,5 @@ export { default as Glog } from "./lib/Glog.js";
14
14
  export { default as Schemer } from "./lib/Schemer.js";
15
15
  export { default as Term } from "./lib/Term.js";
16
16
  export { default as Terms } from "./lib/Terms.js";
17
+ export { default as Disposable, Disposable as DisposableClass } from "./browser/lib/Disposable.js";
17
18
  //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Simple lifecycle helper that tracks disposer callbacks.
3
+ * Register any teardown functions and call dispose() to run them in reverse.
4
+ */
5
+ export default class Disposable {
6
+ /**
7
+ * Registers a disposer callback to be executed when disposed.
8
+ *
9
+ * @param {() => void} disposer - Cleanup callback.
10
+ * @returns {() => void} Function to unregister the disposer.
11
+ */
12
+ registerDisposer(disposer: () => void): () => void;
13
+ /**
14
+ * Runs all registered disposers in reverse order.
15
+ *
16
+ * @returns {void}
17
+ */
18
+ dispose(): void;
19
+ /**
20
+ * Whether disposal has run.
21
+ *
22
+ * @returns {boolean} True when dispose() has already been called.
23
+ */
24
+ get disposed(): boolean;
25
+ /**
26
+ * Read-only list of registered disposers.
27
+ *
28
+ * @returns {Array<() => void>} Snapshot of disposer callbacks.
29
+ */
30
+ get disposers(): Array<() => void>;
31
+ #private;
32
+ }
33
+ //# sourceMappingURL=Disposable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Disposable.d.ts","sourceRoot":"","sources":["../../lib/Disposable.js"],"names":[],"mappings":"AAAA;;;GAGG;AACH;IAIE;;;;;OAKG;IACH,2BAHW,MAAM,IAAI,GACR,MAAM,IAAI,CAStB;IAED;;;;OAIG;IACH,WAFa,IAAI,CAoBhB;IAED;;;;OAIG;IACH,gBAFa,OAAO,CAInB;IAED;;;;OAIG;IACH,iBAFa,KAAK,CAAC,MAAM,IAAI,CAAC,CAI7B;;CAQF"}