be-hive 0.1.14 → 0.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,184 @@
1
+ # be-hive
2
+
3
+ [![Published on webcomponents.org](https://img.shields.io/badge/webcomponents.org-published-blue.svg)](https://www.webcomponents.org/element/bahrus/be-hive)
4
+ [![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/be-hive?style=for-the-badge)](https://bundlephobia.com/result?p=be-hive)
5
+ <img src="http://img.badgesize.io/https://cdn.jsdelivr.net/npm/be-hive?compression=gzip">
6
+ [![NPM version](https://badge.fury.io/js/be-hive.png)](http://badge.fury.io/js/be-hive)
7
+
8
+ ## Overview
9
+
10
+ [be-hive](https://www.youtube.com/watch?v=SQoOwosJWns) lets it [snow in August](https://www.youtube.com/watch?v=m3dmnOtqrV0).
11
+
12
+ be-hive is the coordination layer for the [family of HTML enhancements](https://github.com/bahrus/may-it-be) that follow the "be-enhanced" pattern. It extends the [mount-observer](https://github.com/nicknisi/mount-observer) `Synthesizer` class, providing a declarative custom element (`<be-hive>`) for registering and managing element enhancements within Shadow DOM scopes.
13
+
14
+ In the modern architecture, `be-hive` serves as:
15
+
16
+ 1. A **custom element** (`<be-hive>`) that acts as a registry point inside a Shadow DOM realm
17
+ 2. A **host for EMC (Enhancement Mount Configuration) scripts** that declare which enhancements are active
18
+ 3. A **parser host** for registering attribute parsers used by enhancements
19
+ 4. A **utility provider** (e.g. `findAdjacentElement`) for enhancement implementations
20
+
21
+ ## How It Works
22
+
23
+ The `BeHive` class extends `Synthesizer` from `mount-observer`:
24
+
25
+ ```TypeScript
26
+ import {Synthesizer} from 'mount-observer/Synthesizer.js';
27
+
28
+ export class BeHive extends Synthesizer{}
29
+
30
+ customElements.define('be-hive', BeHive);
31
+ ```
32
+
33
+ When placed inside a Shadow DOM realm, `<be-hive>` processes its child `<script>` elements to configure which enhancements are active in that scope.
34
+
35
+ ## Registering Enhancements
36
+
37
+ Enhancements are registered declaratively using `<script type=emc>` tags inside `<be-hive>`:
38
+
39
+ ```html
40
+ <be-hive>
41
+ <script type=emc src="be-clonable/emc.json"></script>
42
+ <script type=emc src="be-committed/emc.json"></script>
43
+ </be-hive>
44
+ <script type=module>
45
+ import 'be-hive/be-hive.js';
46
+ </script>
47
+ ```
48
+
49
+ Each `<script type=emc>` points to a JSON configuration file (generated from an `emc.mjs` build script) that tells `be-hive` how to observe, parse, and spawn the enhancement.
50
+
51
+ ## The EMC (Enhancement Mount Configuration)
52
+
53
+ Each enhancement project provides an EMC that defines:
54
+
55
+ - **enhKey**: The unique identifier / attribute name for the enhancement
56
+ - **spawn**: The module path to lazily import the enhancement class
57
+ - **withAttrs**: How to map HTML attributes to enhancement properties
58
+
59
+ Example `emc.mjs`:
60
+
61
+ ```javascript
62
+ export const emc = {
63
+ enhConfig: {
64
+ enhKey: 'BeClonable',
65
+ spawn: 'be-clonable/be-clonable.js',
66
+ withAttrs: {
67
+ base: 'be-clonable',
68
+ triggerInsertPosition: '${base}-trigger-insert-position',
69
+ }
70
+ },
71
+ customData: {
72
+ weakRef: {
73
+ properties: ['enhancedElement']
74
+ },
75
+ actions: {
76
+ addCloneBtn: { ifAllOf: ['triggerInsertPosition', 'enhancedElement'] }
77
+ },
78
+ defaultPropVals: {
79
+ triggerInsertPosition: 'beforebegin'
80
+ }
81
+ }
82
+ };
83
+
84
+ export function render(){
85
+ return JSON.stringify(emc, null, 4);
86
+ }
87
+
88
+ console.log(render());
89
+ ```
90
+
91
+ Running `node emc.mjs > emc.json` generates the static JSON configuration that `<be-hive>` loads at runtime.
92
+
93
+ ## Custom Parsers
94
+
95
+ For enhancements with complex attribute syntax, be-hive provides built-in parser wrappers that integrate with the [nested-regex-groups](https://github.com/bahrus/nested-regex-groups) library:
96
+
97
+ - `be-hive/parsers/parse-pattern-statements.js` — for nested object structures using dot notation in capture groups
98
+ - `be-hive/parsers/parse-grouped-capture-statements.js` — for flat objects parsed from multiple statements
99
+
100
+ Register parsers in HTML before loading EMC scripts that depend on them:
101
+
102
+ ```html
103
+ <be-hive>
104
+ <script type=emc-parser
105
+ src="be-hive/parsers/parse-pattern-statements.js"
106
+ parser-name=parse-pattern-statements></script>
107
+ <script type=emc
108
+ src="do-invoke/emc.json"
109
+ wait-for-parsers=parse-pattern-statements></script>
110
+ </be-hive>
111
+ <script type=module>
112
+ import 'be-hive/be-hive.js';
113
+ </script>
114
+ ```
115
+
116
+ ## Emoji Shorthand
117
+
118
+ Many enhancements support both a full name and an emoji shorthand (e.g. `be-clonable` / `⿻`). A separate `.mjs` file generates a variant JSON that overrides the `enhKey` and `base` attribute:
119
+
120
+ ```html
121
+ <!-- Full name -->
122
+ <div be-clonable>...</div>
123
+
124
+ <!-- Emoji shorthand -->
125
+ <div ⿻>...</div>
126
+ ```
127
+
128
+ Both resolve to the same enhancement class; only the observed attribute name differs.
129
+
130
+ ## Utilities
131
+
132
+ be-hive also provides utilities used by enhancement implementations:
133
+
134
+ ### findAdjacentElement
135
+
136
+ Finds an element adjacent to a given element based on an `InsertPosition` and CSS selector:
137
+
138
+ ```javascript
139
+ import {findAdjacentElement} from 'be-hive/findAdjacentElement.js';
140
+
141
+ const trigger = findAdjacentElement('beforebegin', element, '.my-trigger');
142
+ ```
143
+
144
+ ## Exports
145
+
146
+ | Path | Description |
147
+ |------|-------------|
148
+ | `be-hive/be-hive.js` | The `BeHive` custom element (extends Synthesizer) |
149
+ | `be-hive/findAdjacentElement.js` | Adjacent element lookup utility |
150
+ | `be-hive/parsers/parse-pattern-statements.js` | Parser for nested object structures |
151
+ | `be-hive/parsers/parse-grouped-capture-statements.js` | Parser for flat object structures |
152
+
153
+ ## Dependencies
154
+
155
+ - [mount-observer](https://github.com/nicknisi/mount-observer) — Provides the `Synthesizer` base class and the `MountObserver` infrastructure for watching DOM mutations and spawning enhancements
156
+ - [nested-regex-groups](https://github.com/bahrus/nested-regex-groups) — Regex-based attribute parsing library used by the built-in parsers
157
+
158
+ ## Related Projects
159
+
160
+ Key packages in the enhancement ecosystem:
161
+
162
+ - [mount-observer](https://github.com/nicknisi/mount-observer) — Core observation engine
163
+ - [roundabout-lib](https://github.com/bahrus/roundabout-lib) — Reactive property management for enhancements
164
+ - [assign-gingerly](https://github.com/bahrus/assign-gingerly) — Safe property assignment and enhancement gateway
165
+ - [inferencer](https://github.com/bahrus/inferencer) — Element property/event inference
166
+ - [nested-regex-groups](https://github.com/bahrus/nested-regex-groups) — Attribute value parsing
167
+
168
+ Example enhancements built on this architecture:
169
+
170
+ - [be-clonable](https://github.com/bahrus/be-clonable) — Reference implementation
171
+ - [do-invoke](https://github.com/bahrus/do-invoke) — Custom parser reference
172
+ - [be-committed](https://github.com/bahrus/be-committed)
173
+ - [be-bound](https://github.com/bahrus/be-bound) — Two-way data binding
174
+
175
+ ## Viewing Locally
176
+
177
+ 1. Install git
178
+ 2. Fork/clone this repo
179
+ 3. Install node.js
180
+ 4. Open command window to folder where you cloned this repo
181
+ 5. `> git submodule update --init --recursive`
182
+ 6. `> npm install`
183
+ 7. `> npm run serve` (requires a static file server with SSI support)
184
+ 8. Open http://localhost:8000/demo/ in a modern browser (Chrome 146+ recommended for JSON import assertions)
package/be-hive.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Synthesizer } from 'mount-observer/Synthesizer.js';
2
- export class BeHive extends Synthesizer {
3
- }
4
- customElements.define('be-hive', BeHive);
1
+ import { Synthesizer } from 'mount-observer/Synthesizer.js';
2
+ export class BeHive extends Synthesizer {
3
+ }
4
+ customElements.define('be-hive', BeHive);
@@ -1,30 +1,30 @@
1
- export function findAdjacentElement(insertPosition, element, selector) {
2
- switch (insertPosition) {
3
- case 'afterbegin':
4
- case 'beforeend':
5
- return element.querySelector(selector);
6
- break;
7
- case 'beforebegin':
8
- {
9
- let trigger = element.previousElementSibling;
10
- while (trigger !== null) {
11
- if (trigger.matches(selector)) {
12
- return trigger;
13
- }
14
- trigger = trigger.previousElementSibling;
15
- }
16
- return null;
17
- }
18
- case 'afterend':
19
- {
20
- let trigger = element.nextElementSibling;
21
- while (trigger !== null) {
22
- if (trigger.matches(selector)) {
23
- return trigger;
24
- }
25
- trigger = trigger.nextElementSibling;
26
- }
27
- return null;
28
- }
29
- }
30
- }
1
+ export function findAdjacentElement(insertPosition, element, selector) {
2
+ switch (insertPosition) {
3
+ case 'afterbegin':
4
+ case 'beforeend':
5
+ return element.querySelector(selector);
6
+ break;
7
+ case 'beforebegin':
8
+ {
9
+ let trigger = element.previousElementSibling;
10
+ while (trigger !== null) {
11
+ if (trigger.matches(selector)) {
12
+ return trigger;
13
+ }
14
+ trigger = trigger.previousElementSibling;
15
+ }
16
+ return null;
17
+ }
18
+ case 'afterend':
19
+ {
20
+ let trigger = element.nextElementSibling;
21
+ while (trigger !== null) {
22
+ if (trigger.matches(selector)) {
23
+ return trigger;
24
+ }
25
+ trigger = trigger.nextElementSibling;
26
+ }
27
+ return null;
28
+ }
29
+ }
30
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "be-hive",
3
- "version": "0.1.14",
3
+ "version": "0.1.15",
4
4
  "keywords": [
5
5
  "web-components",
6
6
  "web-component",
@@ -1,10 +1,10 @@
1
- import { parseGroupedCaptureStatements as pgcs } from 'nested-regex-groups/parse-grouped-capture-statements.js';
2
- /**
3
- *
4
- * @param {string} value
5
- * @param {*} context
6
- */
7
- export default function parseGroupedCaptureStatements(value, context) {
8
- const result = pgcs(value, context.attrConfig.parserConfig);
9
- return result;
10
- }
1
+ import { parseGroupedCaptureStatements as pgcs } from 'nested-regex-groups/parse-grouped-capture-statements.js';
2
+ /**
3
+ *
4
+ * @param {string} value
5
+ * @param {*} context
6
+ */
7
+ export default function parseGroupedCaptureStatements(value, context) {
8
+ const result = pgcs(value, context.attrConfig.parserConfig);
9
+ return result;
10
+ }
@@ -1,10 +1,11 @@
1
- import { parsePatternStatements as pps } from 'nested-regex-groups/parse-pattern-statements.js';
2
- /**
3
- *
4
- * @param {string} value
5
- * @param {*} context
6
- */
7
- export default function parsePatternStatements(value, context) {
8
- const result = pps(value, context.attrConfig.parserConfig);
9
- return result;
10
- }
1
+ import { parsePatternStatements as pps } from 'nested-regex-groups/parse-pattern-statements.js';
2
+ /**
3
+ *
4
+ * @param {string} value
5
+ * @param {*} context
6
+ */
7
+ export default function parsePatternStatements(value, context) {
8
+ const parserOptions = context.attrConfig.parserOptions;
9
+ const result = pps(value, context.attrConfig.parserConfig, parserOptions);
10
+ return result;
11
+ }
@@ -1,6 +1,6 @@
1
1
  import {parsePatternStatements as pps} from 'nested-regex-groups/parse-pattern-statements.js';
2
2
  import { ParserContext } from '../types/assign-gingerly/types.d.js';
3
- import { PatternConfig } from '../types/nested-regex-groups/types.js';
3
+ import { PatternConfig, ParserOptions } from '../types/nested-regex-groups/types.js';
4
4
 
5
5
  /**
6
6
  *
@@ -8,6 +8,7 @@ import { PatternConfig } from '../types/nested-regex-groups/types.js';
8
8
  * @param {*} context
9
9
  */
10
10
  export default function parsePatternStatements(value: string, context: ParserContext){
11
- const result = pps(value, context.attrConfig.parserConfig as PatternConfig[]);
11
+ const parserOptions = context.attrConfig.parserOptions as ParserOptions | undefined;
12
+ const result = pps(value, context.attrConfig.parserConfig as PatternConfig[], parserOptions);
12
13
  return result;
13
- }
14
+ }