@alwatr/synapse 1.0.0 → 1.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/CHANGELOG.md CHANGED
@@ -3,6 +3,13 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [1.0.1](https://github.com/Alwatr/nanolib/compare/@alwatr/synapse@1.0.0...@alwatr/synapse@1.0.1) (2025-08-26)
7
+
8
+ ### 🐛 Bug Fixes
9
+
10
+ * add missing dependency for @alwatr/delay in package.json ([616025e](https://github.com/Alwatr/nanolib/commit/616025e6d345f16ecedf62761ec96d2ad29c5856))
11
+ * ensure directive update is delayed for proper initialization ([5bc0024](https://github.com/Alwatr/nanolib/commit/5bc0024c52c3813f463141d6508c39090638c4c8))
12
+
6
13
  ## 1.0.0 (2025-08-24)
7
14
 
8
15
  ### ✨ Features
package/README.md CHANGED
@@ -155,3 +155,11 @@ document.body.appendChild(newContent);
155
155
  // You can safely bootstrap again, and it will only process the new button
156
156
  bootstrapDirectives(newContent);
157
157
  ```
158
+
159
+ ## Sponsors
160
+
161
+ The following companies, organizations, and individuals support `nanolib` ongoing maintenance and development. Become a Sponsor to get your logo on our README and website.
162
+
163
+ ### Contributing
164
+
165
+ Contributions are welcome! Please read our [contribution guidelines](https://github.com/Alwatr/.github/blob/next/CONTRIBUTING.md) before submitting a pull request.
@@ -1 +1 @@
1
- {"version":3,"file":"directiveClass.d.ts","sourceRoot":"","sources":["../src/directiveClass.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,8BAAsB,aAAa;IACjC;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,SAAS,SAAC;IAE7B;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,OAAO,wCAAC;IAE3B;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAEzC;;;;OAIG;gBACS,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM;IAUlD;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,OAAO,IAAI,IAAI;IAElC;;;;OAIG;IACH,SAAS,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI;CAI/D"}
1
+ {"version":3,"file":"directiveClass.d.ts","sourceRoot":"","sources":["../src/directiveClass.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,8BAAsB,aAAa;IACjC;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,SAAS,SAAC;IAE7B;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,OAAO,wCAAC;IAE3B;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAEzC;;;;OAIG;gBACS,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM;IAUlD;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,OAAO,IAAI,IAAI;IAElC;;;;OAIG;IACH,SAAS,CAAC,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI;CAI/D"}
package/dist/main.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /* @alwatr/synapse v1.0.0 */
1
+ /* @alwatr/synapse v1.0.1 */
2
2
  "use strict";
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -61,6 +61,7 @@ function directive(selector) {
61
61
  }
62
62
 
63
63
  // src/directiveClass.ts
64
+ var import_delay = require("@alwatr/delay");
64
65
  var import_logger2 = require("@alwatr/logger");
65
66
  var DirectiveBase = class {
66
67
  /**
@@ -73,7 +74,7 @@ var DirectiveBase = class {
73
74
  this.logger_.logMethodArgs?.("new", { selector, element });
74
75
  this.selector_ = selector;
75
76
  this.element_ = element;
76
- this.update_();
77
+ import_delay.delay.immediate().then(() => this.update_());
77
78
  }
78
79
  /**
79
80
  * Dispatches a custom event from the target element.
package/dist/main.cjs.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/main.ts", "../src/lib.ts", "../src/bootstrap.ts", "../src/directiveDecorator.ts", "../src/directiveClass.ts"],
4
- "sourcesContent": ["export * from './bootstrap.js';\nexport * from './directiveDecorator.js';\nexport * from './directiveClass.js';", "import {createLogger} from '@alwatr/logger';\n\nimport type {DirectiveConstructor} from './directiveDecorator.js';\n\n/**\n * Alwatr Synapse Logger.\n */\nexport const logger = createLogger('alwatr/synapse');\n\n/**\n * The registry for all directives.\n */\nexport const directiveRegistry_: {selector: string; constructor: DirectiveConstructor}[] = [];\n", "import {directiveRegistry_, logger} from './lib.js';\n\nconst initializedAttribute = '_synapseConnected';\n\n/**\n * Initializes all registered directives within a given root element.\n * If no root element is provided, it scans the entire body.\n *\n * This function is idempotent; it will not re-initialize a directive on an element\n * that has already been processed.\n *\n * @param rootElement The element to scan for directives. Defaults to `document.body`.\n *\n * @example\n * ```ts\n * // Initialize directives on the whole page after the DOM is loaded.\n * document.addEventListener('DOMContentLoaded', () => bootstrapDirectives());\n *\n * // Or, initialize directives on a dynamically added part of the page.\n * const newContent = document.createElement('div');\n * newContent.innerHTML = '<div class=\"my-button\">Click Me</div>';\n * document.body.appendChild(newContent);\n *\n * bootstrapDirectives(newContent);\n * ```\n */\nexport function bootstrapDirectives(rootElement: Element | Document = document.body): void {\n logger.logMethod?.('bootstrapDirectives');\n\n for (const {selector, constructor} of directiveRegistry_) {\n try {\n const uninitializedSelector = `${selector}:not([${initializedAttribute}])`;\n const elements = rootElement.querySelectorAll<HTMLElement>(uninitializedSelector);\n if (elements.length === 0) continue;\n\n logger.logOther?.(`Found ${elements.length} new element(s) for directive \"${selector}\"`);\n elements.forEach(element => {\n // Mark the element as processed before creating an instance\n element.setAttribute(initializedAttribute, 'true');\n // Instantiate the directive with the element.\n new constructor(element, selector);\n });\n }\n catch (err) {\n logger.error('bootstrapDirectives', 'directive_instantiation_error', err, {selector});\n }\n }\n}\n", "import {directiveRegistry_, logger} from './lib.js';\n\nimport type {DirectiveBase} from './directiveClass.js';\n\n/**\n * Type definition for a directive constructor.\n * A directive class must have a constructor that accepts an HTMLElement.\n */\nexport type DirectiveConstructor<T extends DirectiveBase = DirectiveBase> = new (element: HTMLElement, selector: string) => T;\n\n/**\n * A class decorator that registers a class as a directive.\n *\n * @param selector The CSS selector to which this directive will be attached.\n *\n * @example\n * ```ts\n * @directive('.my-button')\n * class MyButtonDirective extends DirectiveBase {\n * protected update_(): void {\n * this.element_.addEventListener('click', () => console.log('Button clicked!'));\n * }\n * }\n * ```\n */\nexport function directive(selector: string) {\n logger.logMethodArgs?.('@directive', selector);\n\n /**\n * The decorator function that receives the class constructor.\n * @param constructor The class to be registered as a directive.\n */\n return function (constructor: DirectiveConstructor): void {\n directiveRegistry_.push({selector, constructor});\n };\n}\n", "import {createLogger} from '@alwatr/logger';\n\n/**\n * Base class for creating directives that attach behavior to DOM elements.\n * Extend this class to define custom directives.\n */\nexport abstract class DirectiveBase {\n /**\n * The CSS selector for the directive.\n */\n protected readonly selector_;\n\n /**\n * Logger instance for the directive.\n */\n protected readonly logger_;\n\n /**\n * The target DOM element this directive is attached to.\n */\n protected readonly element_: HTMLElement;\n\n /**\n * Constructor to initialize the directive with the target element.\n * @param element - The DOM element this directive is attached to.\n * @param selector - The CSS selector for the directive.\n */\n constructor(element: HTMLElement, selector: string) {\n this.logger_ = createLogger(`directive:${selector}`);\n this.logger_.logMethodArgs?.('new', {selector, element});\n\n this.selector_ = selector;\n this.element_ = element;\n\n this.update_();\n }\n\n /**\n * Called to update the directive's state or behavior.\n * Must be implemented by subclasses.\n */\n protected abstract update_(): void;\n\n /**\n * Dispatches a custom event from the target element.\n * @param eventName - The name of the event.\n * @param detail - Optional data to include in the event.\n */\n protected dispatch_(eventName: string, detail?: unknown): void {\n this.logger_.logMethodArgs?.('dispatch_', {eventName, detail});\n this.element_.dispatchEvent(new CustomEvent(eventName, {detail, bubbles: true}));\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,oBAA2B;AAOpB,IAAM,aAAS,4BAAa,gBAAgB;AAK5C,IAAM,qBAA8E,CAAC;;;ACV5F,IAAM,uBAAuB;AAwBtB,SAAS,oBAAoB,cAAkC,SAAS,MAAY;AACzF,SAAO,YAAY,qBAAqB;AAExC,aAAW,EAAC,UAAU,YAAW,KAAK,oBAAoB;AACxD,QAAI;AACF,YAAM,wBAAwB,GAAG,QAAQ,SAAS,oBAAoB;AACtE,YAAM,WAAW,YAAY,iBAA8B,qBAAqB;AAChF,UAAI,SAAS,WAAW,EAAG;AAE3B,aAAO,WAAW,SAAS,SAAS,MAAM,kCAAkC,QAAQ,GAAG;AACvF,eAAS,QAAQ,aAAW;AAE1B,gBAAQ,aAAa,sBAAsB,MAAM;AAEjD,YAAI,YAAY,SAAS,QAAQ;AAAA,MACnC,CAAC;AAAA,IACH,SACO,KAAK;AACV,aAAO,MAAM,uBAAuB,iCAAiC,KAAK,EAAC,SAAQ,CAAC;AAAA,IACtF;AAAA,EACF;AACF;;;ACtBO,SAAS,UAAU,UAAkB;AAC1C,SAAO,gBAAgB,cAAc,QAAQ;AAM7C,SAAO,SAAU,aAAyC;AACxD,uBAAmB,KAAK,EAAC,UAAU,YAAW,CAAC;AAAA,EACjD;AACF;;;ACnCA,IAAAA,iBAA2B;AAMpB,IAAe,gBAAf,MAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBlC,YAAY,SAAsB,UAAkB;AAClD,SAAK,cAAU,6BAAa,aAAa,QAAQ,EAAE;AACnD,SAAK,QAAQ,gBAAgB,OAAO,EAAC,UAAU,QAAO,CAAC;AAEvD,SAAK,YAAY;AACjB,SAAK,WAAW;AAEhB,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaU,UAAU,WAAmB,QAAwB;AAC7D,SAAK,QAAQ,gBAAgB,aAAa,EAAC,WAAW,OAAM,CAAC;AAC7D,SAAK,SAAS,cAAc,IAAI,YAAY,WAAW,EAAC,QAAQ,SAAS,KAAI,CAAC,CAAC;AAAA,EACjF;AACF;",
4
+ "sourcesContent": ["export * from './bootstrap.js';\nexport * from './directiveDecorator.js';\nexport * from './directiveClass.js';", "import {createLogger} from '@alwatr/logger';\n\nimport type {DirectiveConstructor} from './directiveDecorator.js';\n\n/**\n * Alwatr Synapse Logger.\n */\nexport const logger = createLogger('alwatr/synapse');\n\n/**\n * The registry for all directives.\n */\nexport const directiveRegistry_: {selector: string; constructor: DirectiveConstructor}[] = [];\n", "import {directiveRegistry_, logger} from './lib.js';\n\nconst initializedAttribute = '_synapseConnected';\n\n/**\n * Initializes all registered directives within a given root element.\n * If no root element is provided, it scans the entire body.\n *\n * This function is idempotent; it will not re-initialize a directive on an element\n * that has already been processed.\n *\n * @param rootElement The element to scan for directives. Defaults to `document.body`.\n *\n * @example\n * ```ts\n * // Initialize directives on the whole page after the DOM is loaded.\n * document.addEventListener('DOMContentLoaded', () => bootstrapDirectives());\n *\n * // Or, initialize directives on a dynamically added part of the page.\n * const newContent = document.createElement('div');\n * newContent.innerHTML = '<div class=\"my-button\">Click Me</div>';\n * document.body.appendChild(newContent);\n *\n * bootstrapDirectives(newContent);\n * ```\n */\nexport function bootstrapDirectives(rootElement: Element | Document = document.body): void {\n logger.logMethod?.('bootstrapDirectives');\n\n for (const {selector, constructor} of directiveRegistry_) {\n try {\n const uninitializedSelector = `${selector}:not([${initializedAttribute}])`;\n const elements = rootElement.querySelectorAll<HTMLElement>(uninitializedSelector);\n if (elements.length === 0) continue;\n\n logger.logOther?.(`Found ${elements.length} new element(s) for directive \"${selector}\"`);\n elements.forEach(element => {\n // Mark the element as processed before creating an instance\n element.setAttribute(initializedAttribute, 'true');\n // Instantiate the directive with the element.\n new constructor(element, selector);\n });\n }\n catch (err) {\n logger.error('bootstrapDirectives', 'directive_instantiation_error', err, {selector});\n }\n }\n}\n", "import {directiveRegistry_, logger} from './lib.js';\n\nimport type {DirectiveBase} from './directiveClass.js';\n\n/**\n * Type definition for a directive constructor.\n * A directive class must have a constructor that accepts an HTMLElement.\n */\nexport type DirectiveConstructor<T extends DirectiveBase = DirectiveBase> = new (element: HTMLElement, selector: string) => T;\n\n/**\n * A class decorator that registers a class as a directive.\n *\n * @param selector The CSS selector to which this directive will be attached.\n *\n * @example\n * ```ts\n * @directive('.my-button')\n * class MyButtonDirective extends DirectiveBase {\n * protected update_(): void {\n * this.element_.addEventListener('click', () => console.log('Button clicked!'));\n * }\n * }\n * ```\n */\nexport function directive(selector: string) {\n logger.logMethodArgs?.('@directive', selector);\n\n /**\n * The decorator function that receives the class constructor.\n * @param constructor The class to be registered as a directive.\n */\n return function (constructor: DirectiveConstructor): void {\n directiveRegistry_.push({selector, constructor});\n };\n}\n", "import {delay} from '@alwatr/delay';\nimport {createLogger} from '@alwatr/logger';\n\n/**\n * Base class for creating directives that attach behavior to DOM elements.\n * Extend this class to define custom directives.\n */\nexport abstract class DirectiveBase {\n /**\n * The CSS selector for the directive.\n */\n protected readonly selector_;\n\n /**\n * Logger instance for the directive.\n */\n protected readonly logger_;\n\n /**\n * The target DOM element this directive is attached to.\n */\n protected readonly element_: HTMLElement;\n\n /**\n * Constructor to initialize the directive with the target element.\n * @param element - The DOM element this directive is attached to.\n * @param selector - The CSS selector for the directive.\n */\n constructor(element: HTMLElement, selector: string) {\n this.logger_ = createLogger(`directive:${selector}`);\n this.logger_.logMethodArgs?.('new', {selector, element});\n\n this.selector_ = selector;\n this.element_ = element;\n\n delay.immediate().then(() => this.update_());\n }\n\n /**\n * Called to update the directive's state or behavior.\n * Must be implemented by subclasses.\n */\n protected abstract update_(): void;\n\n /**\n * Dispatches a custom event from the target element.\n * @param eventName - The name of the event.\n * @param detail - Optional data to include in the event.\n */\n protected dispatch_(eventName: string, detail?: unknown): void {\n this.logger_.logMethodArgs?.('dispatch_', {eventName, detail});\n this.element_.dispatchEvent(new CustomEvent(eventName, {detail, bubbles: true}));\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,oBAA2B;AAOpB,IAAM,aAAS,4BAAa,gBAAgB;AAK5C,IAAM,qBAA8E,CAAC;;;ACV5F,IAAM,uBAAuB;AAwBtB,SAAS,oBAAoB,cAAkC,SAAS,MAAY;AACzF,SAAO,YAAY,qBAAqB;AAExC,aAAW,EAAC,UAAU,YAAW,KAAK,oBAAoB;AACxD,QAAI;AACF,YAAM,wBAAwB,GAAG,QAAQ,SAAS,oBAAoB;AACtE,YAAM,WAAW,YAAY,iBAA8B,qBAAqB;AAChF,UAAI,SAAS,WAAW,EAAG;AAE3B,aAAO,WAAW,SAAS,SAAS,MAAM,kCAAkC,QAAQ,GAAG;AACvF,eAAS,QAAQ,aAAW;AAE1B,gBAAQ,aAAa,sBAAsB,MAAM;AAEjD,YAAI,YAAY,SAAS,QAAQ;AAAA,MACnC,CAAC;AAAA,IACH,SACO,KAAK;AACV,aAAO,MAAM,uBAAuB,iCAAiC,KAAK,EAAC,SAAQ,CAAC;AAAA,IACtF;AAAA,EACF;AACF;;;ACtBO,SAAS,UAAU,UAAkB;AAC1C,SAAO,gBAAgB,cAAc,QAAQ;AAM7C,SAAO,SAAU,aAAyC;AACxD,uBAAmB,KAAK,EAAC,UAAU,YAAW,CAAC;AAAA,EACjD;AACF;;;ACnCA,mBAAoB;AACpB,IAAAA,iBAA2B;AAMpB,IAAe,gBAAf,MAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBlC,YAAY,SAAsB,UAAkB;AAClD,SAAK,cAAU,6BAAa,aAAa,QAAQ,EAAE;AACnD,SAAK,QAAQ,gBAAgB,OAAO,EAAC,UAAU,QAAO,CAAC;AAEvD,SAAK,YAAY;AACjB,SAAK,WAAW;AAEhB,uBAAM,UAAU,EAAE,KAAK,MAAM,KAAK,QAAQ,CAAC;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaU,UAAU,WAAmB,QAAwB;AAC7D,SAAK,QAAQ,gBAAgB,aAAa,EAAC,WAAW,OAAM,CAAC;AAC7D,SAAK,SAAS,cAAc,IAAI,YAAY,WAAW,EAAC,QAAQ,SAAS,KAAI,CAAC,CAAC;AAAA,EACjF;AACF;",
6
6
  "names": ["import_logger"]
7
7
  }
package/dist/main.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /* @alwatr/synapse v1.0.0 */
1
+ /* @alwatr/synapse v1.0.1 */
2
2
 
3
3
  // src/lib.ts
4
4
  import { createLogger } from "@alwatr/logger";
@@ -34,6 +34,7 @@ function directive(selector) {
34
34
  }
35
35
 
36
36
  // src/directiveClass.ts
37
+ import { delay } from "@alwatr/delay";
37
38
  import { createLogger as createLogger2 } from "@alwatr/logger";
38
39
  var DirectiveBase = class {
39
40
  /**
@@ -46,7 +47,7 @@ var DirectiveBase = class {
46
47
  this.logger_.logMethodArgs?.("new", { selector, element });
47
48
  this.selector_ = selector;
48
49
  this.element_ = element;
49
- this.update_();
50
+ delay.immediate().then(() => this.update_());
50
51
  }
51
52
  /**
52
53
  * Dispatches a custom event from the target element.
package/dist/main.mjs.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/lib.ts", "../src/bootstrap.ts", "../src/directiveDecorator.ts", "../src/directiveClass.ts"],
4
- "sourcesContent": ["import {createLogger} from '@alwatr/logger';\n\nimport type {DirectiveConstructor} from './directiveDecorator.js';\n\n/**\n * Alwatr Synapse Logger.\n */\nexport const logger = createLogger('alwatr/synapse');\n\n/**\n * The registry for all directives.\n */\nexport const directiveRegistry_: {selector: string; constructor: DirectiveConstructor}[] = [];\n", "import {directiveRegistry_, logger} from './lib.js';\n\nconst initializedAttribute = '_synapseConnected';\n\n/**\n * Initializes all registered directives within a given root element.\n * If no root element is provided, it scans the entire body.\n *\n * This function is idempotent; it will not re-initialize a directive on an element\n * that has already been processed.\n *\n * @param rootElement The element to scan for directives. Defaults to `document.body`.\n *\n * @example\n * ```ts\n * // Initialize directives on the whole page after the DOM is loaded.\n * document.addEventListener('DOMContentLoaded', () => bootstrapDirectives());\n *\n * // Or, initialize directives on a dynamically added part of the page.\n * const newContent = document.createElement('div');\n * newContent.innerHTML = '<div class=\"my-button\">Click Me</div>';\n * document.body.appendChild(newContent);\n *\n * bootstrapDirectives(newContent);\n * ```\n */\nexport function bootstrapDirectives(rootElement: Element | Document = document.body): void {\n logger.logMethod?.('bootstrapDirectives');\n\n for (const {selector, constructor} of directiveRegistry_) {\n try {\n const uninitializedSelector = `${selector}:not([${initializedAttribute}])`;\n const elements = rootElement.querySelectorAll<HTMLElement>(uninitializedSelector);\n if (elements.length === 0) continue;\n\n logger.logOther?.(`Found ${elements.length} new element(s) for directive \"${selector}\"`);\n elements.forEach(element => {\n // Mark the element as processed before creating an instance\n element.setAttribute(initializedAttribute, 'true');\n // Instantiate the directive with the element.\n new constructor(element, selector);\n });\n }\n catch (err) {\n logger.error('bootstrapDirectives', 'directive_instantiation_error', err, {selector});\n }\n }\n}\n", "import {directiveRegistry_, logger} from './lib.js';\n\nimport type {DirectiveBase} from './directiveClass.js';\n\n/**\n * Type definition for a directive constructor.\n * A directive class must have a constructor that accepts an HTMLElement.\n */\nexport type DirectiveConstructor<T extends DirectiveBase = DirectiveBase> = new (element: HTMLElement, selector: string) => T;\n\n/**\n * A class decorator that registers a class as a directive.\n *\n * @param selector The CSS selector to which this directive will be attached.\n *\n * @example\n * ```ts\n * @directive('.my-button')\n * class MyButtonDirective extends DirectiveBase {\n * protected update_(): void {\n * this.element_.addEventListener('click', () => console.log('Button clicked!'));\n * }\n * }\n * ```\n */\nexport function directive(selector: string) {\n logger.logMethodArgs?.('@directive', selector);\n\n /**\n * The decorator function that receives the class constructor.\n * @param constructor The class to be registered as a directive.\n */\n return function (constructor: DirectiveConstructor): void {\n directiveRegistry_.push({selector, constructor});\n };\n}\n", "import {createLogger} from '@alwatr/logger';\n\n/**\n * Base class for creating directives that attach behavior to DOM elements.\n * Extend this class to define custom directives.\n */\nexport abstract class DirectiveBase {\n /**\n * The CSS selector for the directive.\n */\n protected readonly selector_;\n\n /**\n * Logger instance for the directive.\n */\n protected readonly logger_;\n\n /**\n * The target DOM element this directive is attached to.\n */\n protected readonly element_: HTMLElement;\n\n /**\n * Constructor to initialize the directive with the target element.\n * @param element - The DOM element this directive is attached to.\n * @param selector - The CSS selector for the directive.\n */\n constructor(element: HTMLElement, selector: string) {\n this.logger_ = createLogger(`directive:${selector}`);\n this.logger_.logMethodArgs?.('new', {selector, element});\n\n this.selector_ = selector;\n this.element_ = element;\n\n this.update_();\n }\n\n /**\n * Called to update the directive's state or behavior.\n * Must be implemented by subclasses.\n */\n protected abstract update_(): void;\n\n /**\n * Dispatches a custom event from the target element.\n * @param eventName - The name of the event.\n * @param detail - Optional data to include in the event.\n */\n protected dispatch_(eventName: string, detail?: unknown): void {\n this.logger_.logMethodArgs?.('dispatch_', {eventName, detail});\n this.element_.dispatchEvent(new CustomEvent(eventName, {detail, bubbles: true}));\n }\n}\n"],
5
- "mappings": ";;;AAAA,SAAQ,oBAAmB;AAOpB,IAAM,SAAS,aAAa,gBAAgB;AAK5C,IAAM,qBAA8E,CAAC;;;ACV5F,IAAM,uBAAuB;AAwBtB,SAAS,oBAAoB,cAAkC,SAAS,MAAY;AACzF,SAAO,YAAY,qBAAqB;AAExC,aAAW,EAAC,UAAU,YAAW,KAAK,oBAAoB;AACxD,QAAI;AACF,YAAM,wBAAwB,GAAG,QAAQ,SAAS,oBAAoB;AACtE,YAAM,WAAW,YAAY,iBAA8B,qBAAqB;AAChF,UAAI,SAAS,WAAW,EAAG;AAE3B,aAAO,WAAW,SAAS,SAAS,MAAM,kCAAkC,QAAQ,GAAG;AACvF,eAAS,QAAQ,aAAW;AAE1B,gBAAQ,aAAa,sBAAsB,MAAM;AAEjD,YAAI,YAAY,SAAS,QAAQ;AAAA,MACnC,CAAC;AAAA,IACH,SACO,KAAK;AACV,aAAO,MAAM,uBAAuB,iCAAiC,KAAK,EAAC,SAAQ,CAAC;AAAA,IACtF;AAAA,EACF;AACF;;;ACtBO,SAAS,UAAU,UAAkB;AAC1C,SAAO,gBAAgB,cAAc,QAAQ;AAM7C,SAAO,SAAU,aAAyC;AACxD,uBAAmB,KAAK,EAAC,UAAU,YAAW,CAAC;AAAA,EACjD;AACF;;;ACnCA,SAAQ,gBAAAA,qBAAmB;AAMpB,IAAe,gBAAf,MAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBlC,YAAY,SAAsB,UAAkB;AAClD,SAAK,UAAUA,cAAa,aAAa,QAAQ,EAAE;AACnD,SAAK,QAAQ,gBAAgB,OAAO,EAAC,UAAU,QAAO,CAAC;AAEvD,SAAK,YAAY;AACjB,SAAK,WAAW;AAEhB,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaU,UAAU,WAAmB,QAAwB;AAC7D,SAAK,QAAQ,gBAAgB,aAAa,EAAC,WAAW,OAAM,CAAC;AAC7D,SAAK,SAAS,cAAc,IAAI,YAAY,WAAW,EAAC,QAAQ,SAAS,KAAI,CAAC,CAAC;AAAA,EACjF;AACF;",
4
+ "sourcesContent": ["import {createLogger} from '@alwatr/logger';\n\nimport type {DirectiveConstructor} from './directiveDecorator.js';\n\n/**\n * Alwatr Synapse Logger.\n */\nexport const logger = createLogger('alwatr/synapse');\n\n/**\n * The registry for all directives.\n */\nexport const directiveRegistry_: {selector: string; constructor: DirectiveConstructor}[] = [];\n", "import {directiveRegistry_, logger} from './lib.js';\n\nconst initializedAttribute = '_synapseConnected';\n\n/**\n * Initializes all registered directives within a given root element.\n * If no root element is provided, it scans the entire body.\n *\n * This function is idempotent; it will not re-initialize a directive on an element\n * that has already been processed.\n *\n * @param rootElement The element to scan for directives. Defaults to `document.body`.\n *\n * @example\n * ```ts\n * // Initialize directives on the whole page after the DOM is loaded.\n * document.addEventListener('DOMContentLoaded', () => bootstrapDirectives());\n *\n * // Or, initialize directives on a dynamically added part of the page.\n * const newContent = document.createElement('div');\n * newContent.innerHTML = '<div class=\"my-button\">Click Me</div>';\n * document.body.appendChild(newContent);\n *\n * bootstrapDirectives(newContent);\n * ```\n */\nexport function bootstrapDirectives(rootElement: Element | Document = document.body): void {\n logger.logMethod?.('bootstrapDirectives');\n\n for (const {selector, constructor} of directiveRegistry_) {\n try {\n const uninitializedSelector = `${selector}:not([${initializedAttribute}])`;\n const elements = rootElement.querySelectorAll<HTMLElement>(uninitializedSelector);\n if (elements.length === 0) continue;\n\n logger.logOther?.(`Found ${elements.length} new element(s) for directive \"${selector}\"`);\n elements.forEach(element => {\n // Mark the element as processed before creating an instance\n element.setAttribute(initializedAttribute, 'true');\n // Instantiate the directive with the element.\n new constructor(element, selector);\n });\n }\n catch (err) {\n logger.error('bootstrapDirectives', 'directive_instantiation_error', err, {selector});\n }\n }\n}\n", "import {directiveRegistry_, logger} from './lib.js';\n\nimport type {DirectiveBase} from './directiveClass.js';\n\n/**\n * Type definition for a directive constructor.\n * A directive class must have a constructor that accepts an HTMLElement.\n */\nexport type DirectiveConstructor<T extends DirectiveBase = DirectiveBase> = new (element: HTMLElement, selector: string) => T;\n\n/**\n * A class decorator that registers a class as a directive.\n *\n * @param selector The CSS selector to which this directive will be attached.\n *\n * @example\n * ```ts\n * @directive('.my-button')\n * class MyButtonDirective extends DirectiveBase {\n * protected update_(): void {\n * this.element_.addEventListener('click', () => console.log('Button clicked!'));\n * }\n * }\n * ```\n */\nexport function directive(selector: string) {\n logger.logMethodArgs?.('@directive', selector);\n\n /**\n * The decorator function that receives the class constructor.\n * @param constructor The class to be registered as a directive.\n */\n return function (constructor: DirectiveConstructor): void {\n directiveRegistry_.push({selector, constructor});\n };\n}\n", "import {delay} from '@alwatr/delay';\nimport {createLogger} from '@alwatr/logger';\n\n/**\n * Base class for creating directives that attach behavior to DOM elements.\n * Extend this class to define custom directives.\n */\nexport abstract class DirectiveBase {\n /**\n * The CSS selector for the directive.\n */\n protected readonly selector_;\n\n /**\n * Logger instance for the directive.\n */\n protected readonly logger_;\n\n /**\n * The target DOM element this directive is attached to.\n */\n protected readonly element_: HTMLElement;\n\n /**\n * Constructor to initialize the directive with the target element.\n * @param element - The DOM element this directive is attached to.\n * @param selector - The CSS selector for the directive.\n */\n constructor(element: HTMLElement, selector: string) {\n this.logger_ = createLogger(`directive:${selector}`);\n this.logger_.logMethodArgs?.('new', {selector, element});\n\n this.selector_ = selector;\n this.element_ = element;\n\n delay.immediate().then(() => this.update_());\n }\n\n /**\n * Called to update the directive's state or behavior.\n * Must be implemented by subclasses.\n */\n protected abstract update_(): void;\n\n /**\n * Dispatches a custom event from the target element.\n * @param eventName - The name of the event.\n * @param detail - Optional data to include in the event.\n */\n protected dispatch_(eventName: string, detail?: unknown): void {\n this.logger_.logMethodArgs?.('dispatch_', {eventName, detail});\n this.element_.dispatchEvent(new CustomEvent(eventName, {detail, bubbles: true}));\n }\n}\n"],
5
+ "mappings": ";;;AAAA,SAAQ,oBAAmB;AAOpB,IAAM,SAAS,aAAa,gBAAgB;AAK5C,IAAM,qBAA8E,CAAC;;;ACV5F,IAAM,uBAAuB;AAwBtB,SAAS,oBAAoB,cAAkC,SAAS,MAAY;AACzF,SAAO,YAAY,qBAAqB;AAExC,aAAW,EAAC,UAAU,YAAW,KAAK,oBAAoB;AACxD,QAAI;AACF,YAAM,wBAAwB,GAAG,QAAQ,SAAS,oBAAoB;AACtE,YAAM,WAAW,YAAY,iBAA8B,qBAAqB;AAChF,UAAI,SAAS,WAAW,EAAG;AAE3B,aAAO,WAAW,SAAS,SAAS,MAAM,kCAAkC,QAAQ,GAAG;AACvF,eAAS,QAAQ,aAAW;AAE1B,gBAAQ,aAAa,sBAAsB,MAAM;AAEjD,YAAI,YAAY,SAAS,QAAQ;AAAA,MACnC,CAAC;AAAA,IACH,SACO,KAAK;AACV,aAAO,MAAM,uBAAuB,iCAAiC,KAAK,EAAC,SAAQ,CAAC;AAAA,IACtF;AAAA,EACF;AACF;;;ACtBO,SAAS,UAAU,UAAkB;AAC1C,SAAO,gBAAgB,cAAc,QAAQ;AAM7C,SAAO,SAAU,aAAyC;AACxD,uBAAmB,KAAK,EAAC,UAAU,YAAW,CAAC;AAAA,EACjD;AACF;;;ACnCA,SAAQ,aAAY;AACpB,SAAQ,gBAAAA,qBAAmB;AAMpB,IAAe,gBAAf,MAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBlC,YAAY,SAAsB,UAAkB;AAClD,SAAK,UAAUA,cAAa,aAAa,QAAQ,EAAE;AACnD,SAAK,QAAQ,gBAAgB,OAAO,EAAC,UAAU,QAAO,CAAC;AAEvD,SAAK,YAAY;AACjB,SAAK,WAAW;AAEhB,UAAM,UAAU,EAAE,KAAK,MAAM,KAAK,QAAQ,CAAC;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaU,UAAU,WAAmB,QAAwB;AAC7D,SAAK,QAAQ,gBAAgB,aAAa,EAAC,WAAW,OAAM,CAAC;AAC7D,SAAK,SAAS,cAAc,IAAI,YAAY,WAAW,EAAC,QAAQ,SAAS,KAAI,CAAC,CAAC;AAAA,EACjF;AACF;",
6
6
  "names": ["createLogger"]
7
7
  }
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@alwatr/synapse",
3
3
  "description": "Connect your TypeScript classes to the DOM, declaratively.",
4
- "version": "1.0.0",
4
+ "version": "1.0.1",
5
5
  "author": "S. Ali Mihandoost <ali.mihandoost@gmail.com>",
6
6
  "bugs": "https://github.com/Alwatr/nanolib/issues",
7
7
  "dependencies": {
8
+ "@alwatr/delay": "5.5.8",
8
9
  "@alwatr/logger": "5.5.6"
9
10
  },
10
11
  "devDependencies": {
@@ -70,5 +71,5 @@
70
71
  },
71
72
  "type": "module",
72
73
  "types": "./dist/main.d.ts",
73
- "gitHead": "3c92f996e96508ea3a0432539367e34133993647"
74
+ "gitHead": "fd6743a182cf10802c06f76af861ba7a8f3fc9d5"
74
75
  }