mount-observer 0.0.35 → 0.0.37

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/MountObserver.js CHANGED
@@ -32,6 +32,10 @@ export class MountObserver extends EventTarget {
32
32
  #calculatedSelector;
33
33
  #attrParts;
34
34
  #fullListOfEnhancementAttrs;
35
+ async observedAttrs() {
36
+ await this.#selector();
37
+ return this.#fullListOfEnhancementAttrs;
38
+ }
35
39
  //get #attrVals
36
40
  async #selector() {
37
41
  if (this.#calculatedSelector !== undefined)
package/MountObserver.ts CHANGED
@@ -43,6 +43,10 @@ export class MountObserver extends EventTarget implements IMountObserver{
43
43
  #attrParts: Array<AttrParts> | undefined;
44
44
 
45
45
  #fullListOfEnhancementAttrs: Array<string> | undefined;
46
+ async observedAttrs(){
47
+ await this.#selector();
48
+ return this.#fullListOfEnhancementAttrs;
49
+ }
46
50
  //get #attrVals
47
51
  async #selector() : Promise<string>{
48
52
  if(this.#calculatedSelector !== undefined) return this.#calculatedSelector;
package/README.md CHANGED
@@ -11,7 +11,7 @@ Author: Bruce B. Anderson (with valuable feedback from @doeixd )
11
11
 
12
12
  Issues / pr's / polyfill: [mount-observer](https://github.com/bahrus/mount-observer)
13
13
 
14
- Last Update: 2024-9-7
14
+ Last Update: Oct 6, 2024
15
15
 
16
16
  ## Benefits of this API
17
17
 
@@ -19,7 +19,21 @@ What follows is a far more ambitious alternative to the [lazy custom element pro
19
19
 
20
20
  ["Binding from a distance"](https://github.com/WICG/webcomponents/issues/1035#issuecomment-1806393525) refers to empowering the developer to essentially manage their own "stylesheets" -- but rather than for purposes of styling, using these rules to attach behaviors, set property values, etc, to the HTML as it streams in. Libraries that take this approach include [Corset](https://corset.dev/) and [trans-render](https://github.com/bahrus/trans-render). The concept has been promoted by a [number](https://bkardell.com/blog/CSSLike.html) [of](https://www.w3.org/TR/NOTE-AS) [prominent](https://www.xanthir.com/blog/b4K_0) voices in the community.
21
21
 
22
- The underlying theme is this api is meant to make it easy for the developer to do the right thing, by encouraging lazy loading and smaller footprints. It rolls up most all the other observer api's into one, including, potentially, [this one](https://github.com/whatwg/dom/issues/1285), which may be a similar duplicate to [that one](https://github.com/whatwg/dom/issues/1225).
22
+ The underlying theme is this api is meant to make it easy for the developer to do the right thing, by encouraging lazy loading and smaller footprints. It rolls up most all the other observer api's into one, including, potentially, [a selector observor](https://github.com/whatwg/dom/issues/1285), which may be a similar duplicate to [the match-media counterpart proposal](https://github.com/whatwg/dom/issues/1225).
23
+
24
+ Most every web application can be recursively broken down into logical regions, building blocks which are assembled together to form the whole site.
25
+
26
+ At the most micro level, utilizing highly reusable, generic custom elements -- elements that can extend the HTML vocabulary, elements that could be incorporated into the browser, even -- form a great foundation to build on.
27
+
28
+ But as one zooms out from the micro to the macro, the nature of the components changes in significant ways.
29
+
30
+ At the micro level, components will have few, if any, dependencies, and those dependencies will tend to be quite stable, and likely all be used. The dependencies will skew more towards tightly coupled utility libraries.
31
+
32
+ "Macro" level components will tend to be heavy on business-domain specific data, heavy on gluing / orchestrating smaller components, light on difficult, esoteric JavaScript. They aren't confined to static JS files, and likely will include dynamic content as well. They will also be heavy on conditional sections of the application only loading if requested by the user.
33
+
34
+ ES module based web components may or may not be the best fit for these application macro "modules". A better fit might be a server-centric solution, like Rails, just to take an example.
35
+
36
+ A significant pain point has to do with loading all the third-party web components and/or (progressive) enhancements that these macro components / compositions require, and loading them into memory only when needed.
23
37
 
24
38
 
25
39
  ### Does this api make the impossible possible?
@@ -61,16 +75,15 @@ const observer = new MountObserver({
61
75
  if(!customElements.get(localName)) {
62
76
  customElements.define(localName, modules[0].MyElement);
63
77
  }
64
- observer.disconnect();
65
- }
66
- }
78
+ observer.disconnectedSignal.abort();
79
+ },
80
+ },
81
+ disconnectedSignal: new AbortController().signal
67
82
  });
68
83
  observer.observe(document);
69
84
  ```
70
85
 
71
- Invoking "disconnect" as shown above causes the observer to emit event "disconnectedCallback".
72
-
73
- The argument can also be an array of objects that fit the pattern shown above.
86
+ The constructor argument can also be an array of objects that fit the pattern shown above.
74
87
 
75
88
  In fact, as we will see, where it makes sense, where we see examples that are strings, we will also allow for arrays of such strings. For example, the "on" key can point to an array of CSS selectors (and in this case the mount/dismount callbacks would need to provide an index of which one matched). I only recommend adding this complexity if what I suspect is true -- providing this support can reduce "context switching" between threads / memory spaces (c++ vs JavaScript), and thus improve performance. If multiple "on" selectors are provided, and multiple ones match, I think it makes sense to indicate the one with the highest specifier that matches. It would probably be helpful in this case to provide a special event that allows for knowing when the matching selector with the highest specificity changes for mounted elements.
76
89
 
@@ -98,14 +111,14 @@ const observer = new MountObserver({
98
111
  if(!customElements.get(localName)) {
99
112
  customElements.define(localName, modules[1].MyElement);
100
113
  }
101
- observer.disconnect();
114
+ observer.disconnectedSignal.abort();
102
115
  }
103
116
  }
104
117
  });
105
118
  observer.observe(document);
106
119
  ```
107
120
 
108
- Once again, the key can accept either a single import and it can also support multiple imports (via an array).
121
+ Once again, the key can accept either a single import, but alternatively it can also support multiple imports (via an array).
109
122
 
110
123
  The do event won't be invoked until all the imports have been successfully completed and inserted into the modules array.
111
124
 
@@ -113,6 +126,37 @@ Previously, this proposal called for allowing arrow functions as well, thinking
113
126
 
114
127
  This proposal would also include support for JSON and HTML module imports.
115
128
 
129
+ ## Preemptive downloading
130
+
131
+ There are two significant steps to imports, each of which imposes a cost:
132
+
133
+ 1. Downloading the resource.
134
+ 2. Loading the resource into memory.
135
+
136
+ What if we want to download the resource ahead of time, but only load into memory when needed?
137
+
138
+ The link rel=modulepreload option provides an already existing platform support for this, but the browser complains when no use of the resource is used within a short time span of page load. That doesn't really fit the bill for lazy loading custom elements and other resources.
139
+
140
+ So for this we add option:
141
+
142
+ ```JavaScript
143
+ const observer = new MountObserver({
144
+ on: 'my-element',
145
+ loadingEagerness: 'eager',
146
+ import: './my-element.js',
147
+ do:{
148
+ mount: (matchingElement, {modules}) => customElements.define(modules[0].MyElement)
149
+ }
150
+ })
151
+ ```
152
+
153
+ So what this does is only check for the presence of an element with tag name "my-element", and it starts downloading the resource, even before the element has "mounted" based on other criteria.
154
+
155
+ > [!NOTE]
156
+ > As a result of the google IO 2024 talks, I became aware that there is some similarity between this proposal and the [speculation rules api](https://developer.chrome.com/blog/speculation-rules-improvements). This motivated the change to the property from "loading" to loadingEagerness above.
157
+
158
+
159
+
116
160
  ## Mount Observer Script Elements (MOSEs)
117
161
 
118
162
  Following an approach similar to the [speculation api](https://developer.chrome.com/blog/speculation-rules-improvements), we can add a script element anywhere in the DOM:
@@ -124,7 +168,7 @@ Following an approach similar to the [speculation api](https://developer.chrome.
124
168
  if(!customElements.get(localName)) {
125
169
  customElements.define(localName, modules[1].MyElement);
126
170
  }
127
- observer.disconnect();
171
+ observer.disconnectedSignal.abort();
128
172
  }">
129
173
  {
130
174
  "on":"my-element",
@@ -150,7 +194,6 @@ No arrays of settings would be supported within a single tag (as this causes iss
150
194
  > To support the event handlers above, I believe it would require that CSP solutions factor in both the inner content of the script element as well as all the event handlers via the string concatenation operator. I actually think such support is quite critical due to lack of support of import.meta.[some reference to the script element] not being available, as it was pre-ES Modules.
151
195
 
152
196
 
153
-
154
197
  ## Shadow Root inheritance
155
198
 
156
199
  Inside a shadow root, we can plop a script element, also with type "mountobserver", optionally giving it the same id as above:
@@ -175,6 +218,7 @@ But if a matching id is found, then the values from the parent script element ge
175
218
 
176
219
  We will come back to some important [additional features](#creating-frameworks-that-revolve-around-moses) of using these script elements later, but first we want to cover the highlights of this proposal, in order to give more context as to what kinds of functionality these MOSEs can provide.
177
220
 
221
+
178
222
  ## Binding from a distance
179
223
 
180
224
  It is important to note that "on" is a css query with no restrictions. So something like:
@@ -299,6 +343,8 @@ If an element that is in "mounted" state according to a MountObserver instance i
299
343
  5) If the new place it was added remains within the original rootNode and remains mounted, the MountObserver instance dispatches event "reconfirmed".
300
344
  6) If the element no longer satisfies the criteria of the MountObserver instance, the MountObserver instance will dispatch event "dismount".
301
345
 
346
+ Some of the events above are subject to change depending on the outcome of the [atomic moving](https://github.com/whatwg/dom/issues/1255) proposal.
347
+
302
348
  ## Dismounting
303
349
 
304
350
  In many cases, it will be critical to inform the developer **why** the element no longer satisfies all the criteria. For example, we may be using an intersection observer, and when we've scrolled away from view, we can "shut down" until the element is (nearly) scrolled back into view. We may also be displaying things differently depending on the network speed. How we should respond when one of the original conditions, but not the other, no longer applies, is of paramount importance.
@@ -308,7 +354,7 @@ So the dismount event should provide a "checklist" of all the conditions, and th
308
354
  ```JavaScript
309
355
  mediaMatches: true,
310
356
  containerMatches: true,
311
- satisifiesCustomCondition: true,
357
+ satisfiesCustomCondition: true,
312
358
  whereLangIn: ['en-GB'],
313
359
  whereConnection:{
314
360
  effectiveTypeMatches: true
@@ -358,9 +404,9 @@ I think in the vast majority of cases, setting the property values corresponding
358
404
  Usually, there are no events we can subscribe to in order to know when the property changes. Hijacking the property setter in order to observe changes may not always work or feel very resilient. So monitoring the attribute value associated with the property is often the most effective way of observing when the property/attribute state for these elements change. And some attributes (like the microdata attributes such as itemprop) don't even have properties that they pair with!
359
405
 
360
406
 
361
- 2. In contrast, there are scenarios where we want to support somewhat fluid, renamable attributes within different Shadow DOM scopes, which add behavior/enhancement capabilities on top of built-in or third party custom elements. We'll refer to these attributes as "Enhancement Attributes."
407
+ 2. In contrast, there are scenarios where we want to support somewhat fluid, renamable attributes within different Shadow DOM realms, which add behavior/enhancement capabilities on top of built-in or third party custom elements. We'll refer to these attributes as "Enhancement Attributes."
362
408
 
363
- We want our api to be able to distinguish between these two, and to be able to combine both types in one mount observer instance.
409
+ We want our api to be able to distinguish between these two, and to be able to combine both types in one mount observer instance's set of observed attributes.
364
410
 
365
411
  > [!NOTE]
366
412
  > The most important reason for pointing out this distinction is this: "Source of Truth" attributes will only be *observed*, and will **not** trigger mount/unmount states unless they are part of the "on" selector string. And unlike all the other "where" conditions this proposal supports, the where clauses for the "Enhancement Attributes" are "one-way" -- they trigger a "mount" event / callback, followed by the ability to observe the stream of changes (including removal of those attributes), but they never trigger a "dismount".
@@ -573,7 +619,16 @@ Possibly some libraries may prefer to mix it up a bit:
573
619
  </div>
574
620
  ```
575
621
 
576
- To support such syntax, specify the delimiter thusly:
622
+ An example of this in the real world can be found with [HTMX](https://htmx.org/docs/#hx-on):
623
+
624
+ ```html
625
+ <button hx-post="/example"
626
+ hx-on:htmx:config-request="event.detail.parameters.example = 'Hello Scripting!'">
627
+ Post Me!
628
+ </button>
629
+ ```
630
+
631
+ To support such syntax, specify the delimiters thusly:
577
632
 
578
633
  ```JavaScript
579
634
  const mo = new MountObserver({
@@ -589,47 +644,42 @@ const mo = new MountObserver({
589
644
  });
590
645
  ```
591
646
 
592
- ## Resolving ambiguity
593
-
594
- Because we want the multiple root values (enh-*, data-enh-*, *) to be treated as equivalent, from a developer point of view, we have a possible ambiguity -- what if more than one root is present for the same base, branch and leaf? Which value trumps the others?
595
-
596
- Tentative rules:
597
-
598
- 1. Roots must differ in length.
599
- 2. If one value is null (attribute not present) and the other a string, the one with the string value trumps.
600
- 3. If two or more equivalent attributes have string values, the one with the longer root prevails.
647
+ ## Supporting userland security protections
601
648
 
602
- The thinking here is that longer roots indicate higher "specificity", so it is safer to use that one.
649
+ As we saw with the HTMX example above, element enhancement libraries that (progressively) enhance server rendered HTML are finding it necessary to support inline event handling. Since the platform has provided no support for hashing built-in event handlers, there's no real advantage for these libraries to utilize the built-in event handlers, so might as well create bespoke event handlers, which unfortunately might not be detected by browser security mechanisms. Perhaps some of these libraries only enable that functionality after confirming no such CSP rules are in place, or provide console warnings, who knows? This reminds me of the plausible (but probably not universally held) belief that illegalizing relatively safe recreational drugs like hashish or beer pushes the illegal market to gravitate towards drugs/beverages which have more "bang for the buck", which are considerably less safe, leading to the conclusion that the "health and safety" laws end up causing more harm than good.
603
650
 
651
+ I am personally pursuing a [userland implementation of CSP tailored for attributes](https://github.com/bahrus/be-hashing-out). What I'm finding necessary to support this is a way to quickly determine *the full list of* attributes a particular enhancement is monitoring for.
604
652
 
605
- ## Preemptive downloading
653
+ Thus the mountObserver does provide that information to the consumer as well:
606
654
 
607
- There are two significant steps to imports, each of which imposes a cost:
655
+ ```JavaScript
656
+ const mo = new MountObserver({
657
+ on: '*',
658
+ whereAttr:{
659
+ hasRootIn: ['data', 'enh', 'data-enh'],
660
+ hasBase: ['-', 'my-enhancement'],
661
+ hasBranchIn: [':', ['first-aspect', 'second-aspect', '']],
662
+ hasLeafIn: {
663
+ 'first-aspect': ['--', ['wow-this-is-deep', 'have-you-considered-using-json-for-this']],
664
+ }
665
+ }
666
+ });
667
+ const observedAttributes = await mo.observedAttrs();
668
+ ```
608
669
 
609
- 1. Downloading the resource.
610
- 2. Loading the resource into memory.
670
+ ## Resolving ambiguity
611
671
 
612
- What if we want to download the resource ahead of time, but only load into memory when needed?
672
+ Because we want the multiple root values (enh-*, data-enh-*, *) to be treated as equivalent, from a developer point of view, we have a possible ambiguity -- what if more than one root is present for the same base, branch and leaf? Which value prevails over the others?
613
673
 
614
- The link rel=modulepreload option provides an already existing platform support for this, but the browser complains when no use of the resource is used within a short time span of page load. That doesn't really fit the bill for lazy loading custom elements and other resources.
674
+ Tentative rules:
615
675
 
616
- So for this we add option:
676
+ 1. Roots must differ in length.
677
+ 2. If one value is null (attribute not present) and the other a string, the one with the string value prevails.
678
+ 3. If two or more equivalent attributes have string values, the one with the longer root prevails.
617
679
 
618
- ```JavaScript
619
- const observer = new MountObserver({
620
- on: 'my-element',
621
- loadingEagerness: 'eager',
622
- import: './my-element.js',
623
- do:{
624
- mount: (matchingElement, {modules}) => customElements.define(modules[0].MyElement)
625
- }
626
- })
627
- ```
680
+ The thinking here is that longer roots indicate higher "specificity", so it is safer to use that one.
628
681
 
629
- So what this does is only check for the presence of an element with tag name "my-element", and it starts downloading the resource, even before the element has "mounted" based on other criteria.
630
682
 
631
- > [!NOTE]
632
- > As a result of the google IO 2024 talks, I became aware that there is some similarity between this proposal and the [speculation rules api](https://developer.chrome.com/blog/speculation-rules-improvements). This motivated the change to the property from "loading" to loadingEagerness above.
633
683
 
634
684
  ## Intra document html imports
635
685
 
@@ -733,6 +783,8 @@ This proposal (and polyfill) also supports the option to utilize ShadowDOM / slo
733
783
 
734
784
  The discussion there leads to an open question whether a processing instruction would be better. I think the compose tag would make much more sense, vs a processing instruction, as it could then support slotted children (behaving similar to the Beatles' example above). Or maybe another tag should be introduced that is the equivalent of the slot, to avoid confusion. But I strongly suspect that could significantly reduce the payload size of some documents, if we can reuse blocks of HTML, inserting sections of customized content for each instance.
735
785
 
786
+ The [add src attribute to template to load a template from file](https://github.com/whatwg/html/issues/10571) and an interesting proposal that is [coming from](https://github.com/htmlcomponents/declarative-shadow-imports/blob/main/examples/02-explainer-proposal/02-html.html) the Edge team [seem quite compatible](https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/ShadowDOM/explainer.md#proposal-inline-declarative-css-module-scripts) with this idea.
787
+
736
788
  ## Creating "frameworks" that revolve around MOSEs.
737
789
 
738
790
  Often, we will want to define a large number of "mount observer script elements (MOSEs)" programmatically, and we need it to be done in a generic way, that can be published and easily referenced.
package/Synthesizer.js CHANGED
@@ -49,6 +49,7 @@ export class Synthesizer extends HTMLElement {
49
49
  activate(mose) {
50
50
  if (!this.checkIfAllowed(mose))
51
51
  return;
52
+ mose.dispatchEvent(new LoadEvent());
52
53
  const { init, do: d } = mose;
53
54
  const mi = {
54
55
  do: d,
@@ -116,3 +117,9 @@ export class SynthesizeEvent extends Event {
116
117
  this.mountObserverElement = mountObserverElement;
117
118
  }
118
119
  }
120
+ export class LoadEvent extends Event {
121
+ static eventName = 'load';
122
+ constructor() {
123
+ super(LoadEvent.eventName);
124
+ }
125
+ }
@@ -1,6 +1,6 @@
1
1
  export async function getWhereAttrSelector(whereAttr, withoutAttrs) {
2
2
  const { hasBase, hasBranchIn, hasRootIn } = whereAttr;
3
- const fullListOfAttrs = [];
3
+ let fullListOfAttrs = [];
4
4
  const partitionedAttrs = [];
5
5
  if (hasBase !== undefined) {
6
6
  const hasRootInGuaranteed = hasRootIn || [{
@@ -72,6 +72,7 @@ export async function getWhereAttrSelector(whereAttr, withoutAttrs) {
72
72
  }
73
73
  }
74
74
  }
75
+ fullListOfAttrs = Array.from(new Set(fullListOfAttrs));
75
76
  const listOfSelectors = fullListOfAttrs.map(s => `${withoutAttrs}[${s}]`);
76
77
  const calculatedSelector = listOfSelectors.join(',');
77
78
  return {
@@ -2,13 +2,13 @@ import {AttrParts, RootCnfg, WhereAttr} from './ts-refs/mount-observer/types';
2
2
  export async function getWhereAttrSelector(whereAttr: WhereAttr, withoutAttrs: string){
3
3
  const {hasBase, hasBranchIn, hasRootIn} = whereAttr;
4
4
 
5
- const fullListOfAttrs: Array<string> = [];
5
+ let fullListOfAttrs: Array<string> = [];
6
6
  const partitionedAttrs: Array<AttrParts> = [];
7
7
  if(hasBase !== undefined){
8
8
  const hasRootInGuaranteed: Array<RootCnfg> = hasRootIn || [{
9
9
  start: '',
10
10
  context: 'Both'
11
- } as RootCnfg]
11
+ } as RootCnfg];
12
12
 
13
13
  let prefixLessMatches: Array<{
14
14
  rootToBaseDelimiter: string,
@@ -80,7 +80,7 @@ export async function getWhereAttrSelector(whereAttr: WhereAttr, withoutAttrs: s
80
80
  }
81
81
  }
82
82
 
83
-
83
+ fullListOfAttrs = Array.from(new Set(fullListOfAttrs));
84
84
  const listOfSelectors = fullListOfAttrs.map(s => `${withoutAttrs}[${s}]`);
85
85
  const calculatedSelector = listOfSelectors.join(',');
86
86
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mount-observer",
3
- "version": "0.0.35",
3
+ "version": "0.0.37",
4
4
  "description": "Observe and act on css matches.",
5
5
  "main": "MountObserver.js",
6
6
  "module": "MountObserver.js",
@@ -1,25 +1,22 @@
1
- import {BEAllProps, IEnhancement} from '../trans-render/be/types';
1
+ import {BEAllProps, EventListenerOrFn, IEnhancement} from '../trans-render/be/types';
2
2
  import {StringWithAutocompleteOptions} from '../trans-render/types';
3
3
  import { Specifier } from '../trans-render/dss/types';
4
4
  import {AbsorbingObject} from '../trans-render/asmr/types';
5
+ import {Handlers} from '../be-hive/types';
5
6
 
6
7
  export interface EndUserProps extends IEnhancement<HTMLElement>{
7
8
  forAttr?: string,
8
- //onInput?: string,
9
- //onChange?: string,
10
- //onLoad?: string,
11
- //assignTo?: Array<Specifier>,
12
- nameOfCalculator: string,
9
+ handler: string
13
10
  eventArg: string,
14
11
  }
15
12
 
16
13
  export interface AllProps extends EndUserProps{
17
- calculator: {new: () => EventListenerObject},
14
+ //calculator: {new: () => EventListenerObject},
18
15
  // value: any;
19
16
  // isParsed: boolean;
20
17
  // attrExpr?: string | null;
21
- scriptEl?: HTMLScriptElement;
22
- publishEventType: 'input' | 'change' | 'load',
18
+ //publishEventType: 'input' | 'change' | 'load',
19
+ handlerObj?: EventListenerOrFn,
23
20
  defaultEventType: StringWithAutocompleteOptions<
24
21
  | 'input'
25
22
  | 'change'
@@ -32,7 +29,7 @@ export interface AllProps extends EndUserProps{
32
29
  categorized?: boolean,
33
30
  remSpecifierLen?: number,
34
31
  propToAO: {[key: string] : AbsorbingObject},
35
- hasInlineEvent: boolean,
32
+ checkedRegistry: boolean,
36
33
  }
37
34
 
38
35
  export type AP = AllProps;
@@ -55,14 +52,15 @@ export type ProPAP = Promise<PAP>
55
52
  // //onValue(self: this): void;
56
53
  // }
57
54
 
58
- export type BAP = AP & BEAllProps;
55
+ export type BAP = AP & BEAllProps & Handlers;
59
56
 
60
57
  export interface Actions{
61
58
  categorizeEl(self: BAP): PAP;
59
+ getEvtHandler(self: BAP): PAP;
62
60
  parseForAttr(self: BAP): PAP;
63
61
  getDefltEvtType(self: BAP): PAP;
64
- findScriptEl(self: BAP): PAP;
65
- importSymbols(self: BAP): ProPAP;
62
+ // findScriptEl(self: BAP): PAP;
63
+ // importSymbols(self: BAP): ProPAP;
66
64
  genRemoteSpecifiers(self: BAP): PAP;
67
65
  seek(self: BAP): ProPAP;
68
66
  hydrate(self: BAP): ProPAP;
@@ -0,0 +1,26 @@
1
+ import {BEAllProps, IEnhancement} from '../trans-render/be/types';
2
+ import { RoundaboutReady } from '../trans-render/froop/types';
3
+
4
+ export interface EndUserProps extends IEnhancement{
5
+ to: string;
6
+ nudges: boolean;
7
+ on: string;
8
+ }
9
+
10
+ export interface AllProps extends EndUserProps {
11
+ //isParsed?: boolean;
12
+ }
13
+
14
+ export type AP = AllProps;
15
+
16
+ export type PAP = Partial<AP>;
17
+
18
+ export type ProPAP = Promise<PAP>;
19
+
20
+ export type BAP = AllProps & BEAllProps & RoundaboutReady;
21
+
22
+ export interface Actions{
23
+ hydrate(self: BAP): ProPAP;
24
+ // findTarget(self: this): Promise<void>;
25
+ // handleCommit(self: this, e: KeyboardEvent): Promise<void>;
26
+ }
@@ -0,0 +1,88 @@
1
+ import {BEAllProps, IEnhancement} from '../trans-render/be/types';
2
+ import { Specifier } from "../trans-render/dss/types";
3
+ import { RoundaboutReady } from '../trans-render/froop/types';
4
+
5
+ export interface EndUserPropsBasic extends IEnhancement{
6
+ /**
7
+ * How much to increment on each event
8
+ */
9
+ step: number;
10
+ /**
11
+ * Don't allow count to exceed this number
12
+ */
13
+ ltOrEq?: number;
14
+ /** Don't allow count to reach this number. */
15
+ lt?: number;
16
+ /**
17
+ * Starting value of count, including after looping
18
+ */
19
+ min?: number;
20
+ /**
21
+ * Make count loop back to min value after hitting the ceiling set by ltOrEq or lt
22
+ */
23
+ loop?: boolean;
24
+
25
+ /**
26
+ * Slowly "awakens" a disabled element. If the disabled attribute is not set to a number, or is set to "1", removes the disabled attribute. If it is a larger number, decrements the number by 1.
27
+ */
28
+ nudges?: boolean;
29
+ /**
30
+ * Event name to trigger count increment
31
+ */
32
+ incOn: string;
33
+ /**
34
+ * Property to subscribe to trigger count increment
35
+ * [TODO]
36
+ */
37
+ incOnSet?: string;
38
+ /**
39
+ * Disable on max
40
+ */
41
+ disableOnMax?: boolean;
42
+ /**
43
+ * set lt = 1
44
+ * and min = 0
45
+ * and step = 1
46
+ * and disableOnMax = true
47
+ */
48
+ once?: boolean
49
+ }
50
+ export interface EndUserProps extends EndUserPropsBasic, IEnhancement {
51
+
52
+ }
53
+
54
+ export interface AllProps extends EndUserProps{
55
+ count: number;
56
+ value: number;
57
+ parsedStatements?: Array<SharingParameters>;
58
+ //checked: boolean;
59
+ isMaxedOut?: boolean;
60
+ //isParsed?: boolean;
61
+ //transformer?: ITransformer<EndUserPropsBasic, Actions, {}>
62
+ }
63
+
64
+ export interface SharingParameters{
65
+ localProp: string,
66
+ remoteSpecifiers: Array<Specifier>
67
+ }
68
+
69
+
70
+ export type AP = AllProps;
71
+
72
+ export type PAP = Partial<AP>;
73
+
74
+ export type ProPAP = Promise<PAP>
75
+
76
+ export type BAP = AllProps & BEAllProps & RoundaboutReady;
77
+
78
+ export interface Actions{
79
+ hydrate(self: BAP): ProPAP;
80
+ onCount(self: BAP): PAP;
81
+ //shareValue(self: BAP): ProPAP;
82
+ onOnce(self: BAP): PAP
83
+ // inc(self: this): PAP;
84
+ // disableInc(self: this): POA;
85
+ // check(self: this, allGood: PAP): PAP;
86
+ // hydrateTransform(self: this): ProPAP;
87
+ }
88
+
@@ -0,0 +1,22 @@
1
+ import {BEAllProps, IEnhancement} from '../trans-render/be/types';
2
+
3
+ export interface EndUserProps extends IEnhancement{
4
+ digest: string;
5
+ }
6
+
7
+ export interface AllProps extends EndUserProps {
8
+
9
+ }
10
+
11
+ export type AP = AllProps;
12
+
13
+ export type PAP = Partial<AP>;
14
+
15
+ export type ProPAP = Promise<PAP>;
16
+
17
+ export type BAP = AP & BEAllProps;
18
+
19
+ export interface Actions{
20
+ logDigest(self: BAP): ProPAP;
21
+ checkDigest(self: BAP): ProPAP;
22
+ }
@@ -0,0 +1,18 @@
1
+ import { CustomHandlers, ScopedCustomHandlers } from '../trans-render/be/types';
2
+ import {StringWithAutocompleteOptions} from '../trans-render/types';
3
+ export type aggKeys = StringWithAutocompleteOptions<
4
+ | '+'
5
+ | '*'
6
+ | 'max'
7
+ | 'min'
8
+ | 'nearlyEq'
9
+ | 'eq'
10
+ | '||'
11
+ | '&&'
12
+ | '{}'
13
+ >;
14
+
15
+ export interface Handlers{
16
+ customHandlers: CustomHandlers;
17
+ scopedCustomHandlers?: ScopedCustomHandlers;
18
+ }
@@ -0,0 +1,28 @@
1
+ import {IEnhancement, BEAllProps} from '../trans-render/be/types';
2
+ import { Specifier } from '../trans-render/dss/types';
3
+
4
+ export interface EndUserProps extends IEnhancement{
5
+
6
+ }
7
+
8
+ export interface AP extends EndUserProps{
9
+ parsedStatements?: Array<InvokingParameters>,
10
+ rawStatements?: Array<string>,
11
+ }
12
+
13
+ export type AllProps = AP;
14
+
15
+ export type PAP = Partial<AP>;
16
+
17
+ export type ProPAP = Promise<PAP>
18
+
19
+ export type BAP = AP & BEAllProps;
20
+
21
+ export interface Actions{
22
+ hydrate(self: this): ProPAP;
23
+ }
24
+
25
+ export interface InvokingParameters {
26
+ remoteSpecifiers: Array<Specifier>,
27
+ localEventType?: string,
28
+ }
@@ -0,0 +1,73 @@
1
+ import {BEAllProps, IEnhancement} from '../trans-render/be/types';
2
+ import { Specifier } from "../trans-render/dss/types";
3
+ import {aggKeys, Handlers} from '../be-hive/types';
4
+ import { StringWithAutocompleteOptions } from '../trans-render/types';
5
+ import {AbsorbingObject} from '../trans-render/asmr/types';
6
+ export interface EndUserProps extends IEnhancement{
7
+
8
+ }
9
+
10
+ export interface AllProps extends EndUserProps{
11
+ //observedFactors?: Array<Specifier>,
12
+ parsedStatements: Array<ObservingParameters>,
13
+ //bindings?: Array<EndPoints>,
14
+ rawStatements?: Array<string>,
15
+ didInferring?: boolean,
16
+
17
+ }
18
+
19
+
20
+
21
+
22
+ export type AP = AllProps;
23
+
24
+ export type PAP = Partial<AP>;
25
+
26
+ export type ProPAP = Promise<PAP>;
27
+
28
+ export type BAP = AP & BEAllProps & Handlers;
29
+
30
+ export interface Actions{
31
+ noAttrs(self: BAP): ProPAP;
32
+ infer(self: BAP) : ProPAP;
33
+ seek(self: BAP): ProPAP;
34
+ // hydrate(self: this): ProPAP;
35
+ warn(...data: any[]): void;
36
+ }
37
+
38
+ export interface AndIfThen{
39
+ ifCondition: string,
40
+ passValue: string,
41
+ }
42
+
43
+ export interface ObservingParameters{
44
+ localPropToSet?: string,
45
+ remoteSpecifiers: Array<Specifier>,
46
+ mappings?: Array<AndIfThen>,
47
+ aggKey: StringWithAutocompleteOptions<aggKeys>,
48
+ //aggregateRemoteVals?: 'Union' | 'Conjunction' | 'ObjectAssign' | 'Sum' | 'Product' | 'ArrayPush'
49
+ }
50
+
51
+
52
+
53
+
54
+
55
+
56
+ // export interface ObserverOptions{
57
+ // abortControllers: Array<AbortController>,
58
+ // remoteEl?: Element,
59
+ // }
60
+
61
+ export type LoadEventName = 'load';
62
+
63
+ export interface EventForObserver{
64
+ factors: {[key: string | number] : any},
65
+ setProps?: {[key: string]: any};
66
+ enh: string,
67
+ }
68
+
69
+ // export interface ObserverEventModel{
70
+ // factors: {[key: string] : any},
71
+ // vals: any[],
72
+
73
+ // }
@@ -0,0 +1,140 @@
1
+ //import { ActionOnEventConfigs } from "trans-render/froop/types";
2
+ import {BEAllProps, IEnhancement} from '../trans-render/be/types';
3
+ //import {BVAAllProps} from 'be-value-added/types';
4
+ //import {AP as BPAP, ISignal, Actions as BPActions} from 'be-propagating/types';
5
+ //import {ElTypes, SignalRefType} from 'be-linked/types';
6
+ //import { Propagator } from "../trans-render/froop/PropSvc";
7
+ import {Specifier} from '../trans-render/dss/types';
8
+
9
+ export interface EndUserProps extends IEnhancement<HTMLTemplateElement>{
10
+ lhs?: any,
11
+ rhs?: any,
12
+ ifMediaMatches?: string,
13
+ checkIfNonEmptyArray?: boolean;
14
+ op?: '===';
15
+ /**
16
+ * If lhs and/or rhs is boolean, just check that truthiness matches.
17
+ */
18
+ beBoolish: boolean;
19
+ displayDelay?: number;
20
+ hiddenStyle?: string;
21
+ toggleInert?: boolean;
22
+ deferRendering?: boolean;
23
+ minMem?: boolean;
24
+ /**
25
+ * Works with beOosoom decorator, so becomes inert when out of view
26
+ */
27
+ beOosoom?: string;
28
+ // On?: Array<SwitchStatement>;
29
+ // on?: Array<SwitchStatement>;
30
+ // Off?: Array<SwitchStatement>;
31
+ // off?: Array<SwitchStatement>;
32
+ }
33
+
34
+ export interface AllProps extends EndUserProps{
35
+ val: boolean,
36
+ singleValSwitchesSatisfied?: boolean,
37
+ singleValSwitchNoGo?: boolean,
38
+ twoValSwitchesSatisfied?: boolean,
39
+ twoValSwitchNoGo?: boolean,
40
+ switchesSatisfied?: boolean,
41
+ echoVal: boolean,
42
+ singleValSwitches: Array<OneValueSwitch>,
43
+ twoValueSwitches: Array<TwoValueSwitch>,
44
+ offBinarySwitches?: Array<OneValueSwitch>,
45
+ nValueSwitches?: Array<NValueScriptSwitch>
46
+ rawStatements?: Array<string>
47
+ }
48
+
49
+ export type SwitchStatement = string;
50
+
51
+
52
+ export interface OneValueSwitch{
53
+ ifPart: string,
54
+ specifier: Specifier,
55
+ //signal?: WeakRef<SignalRefType>,
56
+ req?: boolean,
57
+ }
58
+
59
+ export type Op = 'equals' | 'eq' | 'lt' | 'gt';
60
+
61
+ export interface TwoPartOpStatement{
62
+ lhsPart: string,
63
+ op: Op,
64
+ rhsPart: string,
65
+ within: string,
66
+ }
67
+
68
+ export interface TwoValueSwitch{
69
+ lhsSpecifier: Specifier,
70
+ rhsSpecifier: Specifier,
71
+ withinSpecifier?: Specifier,
72
+ req?: boolean,
73
+ op?: Op,
74
+ negate?: boolean,
75
+ lhs?: ISide,
76
+ rhs?: ISide,
77
+ }
78
+
79
+ export interface Dependency extends Specifier{}
80
+
81
+ export interface CanBeSwitchedOn {
82
+ switchedOn?: boolean,
83
+ }
84
+
85
+ export interface NValueScriptSwitch extends CanBeSwitchedOn {
86
+ dependsOn?: string,
87
+ dependencies: Array<Dependency>,
88
+ registeredHandler?: string,
89
+ }
90
+
91
+ export type AP = AllProps;
92
+
93
+ export type PAP = Partial<AP>;
94
+
95
+ export type ProPAP = Promise<PAP>;
96
+
97
+ export type BAP = AP & BEAllProps;
98
+
99
+ export interface Actions{
100
+ calcSwitchesSatisfied(self: this): PAP;
101
+ calcVal(self: this): PAP;
102
+ onTrue(self: this): Promise<void>;
103
+ onFalse(self: this): Promise<void>;
104
+ // addMediaListener(self: this): POA;
105
+ // chkMedia(self: this, e: MediaQueryListEvent): PAP;
106
+
107
+ // doOnBinarySwitches(self: this): Promise<void>;
108
+ onSingleValSwitches(self: this): Promise<void>;
109
+ onTwoValSwitches(self: this): Promise<void>;
110
+ onNValSwitches(self: this): Promise<void>;
111
+ onRawStatements(self: this): void;
112
+ }
113
+
114
+
115
+
116
+ // https://github.com/webcomponents-cg/community-protocols/issues/12#issuecomment-872415080
117
+ //export type loadEventName = 'load';
118
+ export type inputEventName = 'input';
119
+ //export type changeEventName = 'change';
120
+
121
+ export interface ISide {
122
+ val: any
123
+ }
124
+
125
+ export interface Elevate {
126
+ val: any,
127
+ to: string
128
+ }
129
+
130
+ export interface EventForNValueSwitch {
131
+ ctx: NValueScriptSwitch,
132
+ factors: {[key: string] : SignalRefType},
133
+ switchOn?: boolean,
134
+ elevate?: Elevate
135
+ }
136
+
137
+ export interface SignalAndEvent {
138
+ signal?: WeakRef<SignalRefType>,
139
+ eventSuggestion?: string
140
+ }