mount-observer 0.1.34 → 0.1.36

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/Synthesizer.js CHANGED
@@ -215,16 +215,25 @@ export class Synthesizer extends HTMLElement {
215
215
  // Check if export property exists
216
216
  let exportValue = scriptElement.export;
217
217
  if (!exportValue) {
218
- // Wait for resolved event with timeout
219
- const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout waiting for resolved event')), 5000));
220
- const eventPromise = waitForEvent(scriptElement, 'resolved');
218
+ // Determine which event to wait for based on script type
219
+ const scriptType = scriptElement.getAttribute('type');
220
+ const eventName = scriptType === 'emc-parser' ? 'parser-registered' : 'resolved';
221
+ // Wait for appropriate event with timeout
222
+ const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error(`Timeout waiting for ${eventName} event`)), 5000));
223
+ const eventPromise = waitForEvent(scriptElement, eventName);
221
224
  const event = await Promise.race([eventPromise, timeoutPromise]);
222
- exportValue = event.export;
225
+ // For parser scripts, we don't need an export value
226
+ // For other scripts, get the export from the event
227
+ if (scriptType !== 'emc-parser') {
228
+ exportValue = event.export;
229
+ }
223
230
  }
224
231
  // Clone the script element
225
232
  const clonedScript = scriptElement.cloneNode(true);
226
- // Copy the export property
227
- clonedScript.export = exportValue;
233
+ // Copy the export property if it exists
234
+ if (exportValue !== undefined) {
235
+ clonedScript.export = exportValue;
236
+ }
228
237
  // Append to this element's children
229
238
  this.appendChild(clonedScript);
230
239
  }
package/Synthesizer.ts CHANGED
@@ -243,22 +243,33 @@ export abstract class Synthesizer extends HTMLElement {
243
243
  let exportValue = (scriptElement as any).export;
244
244
 
245
245
  if (!exportValue) {
246
- // Wait for resolved event with timeout
246
+ // Determine which event to wait for based on script type
247
+ const scriptType = scriptElement.getAttribute('type');
248
+ const eventName = scriptType === 'emc-parser' ? 'parser-registered' : 'resolved';
249
+
250
+ // Wait for appropriate event with timeout
247
251
  const timeoutPromise = new Promise((_, reject) =>
248
- setTimeout(() => reject(new Error('Timeout waiting for resolved event')), 5000)
252
+ setTimeout(() => reject(new Error(`Timeout waiting for ${eventName} event`)), 5000)
249
253
  );
250
254
 
251
- const eventPromise = waitForEvent(scriptElement, 'resolved');
255
+ const eventPromise = waitForEvent(scriptElement, eventName);
252
256
 
253
257
  const event = await Promise.race([eventPromise, timeoutPromise]);
254
- exportValue = (event as any).export;
258
+
259
+ // For parser scripts, we don't need an export value
260
+ // For other scripts, get the export from the event
261
+ if (scriptType !== 'emc-parser') {
262
+ exportValue = (event as any).export;
263
+ }
255
264
  }
256
265
 
257
266
  // Clone the script element
258
267
  const clonedScript = scriptElement.cloneNode(true) as HTMLScriptElement;
259
268
 
260
- // Copy the export property
261
- (clonedScript as any).export = exportValue;
269
+ // Copy the export property if it exists
270
+ if (exportValue !== undefined) {
271
+ (clonedScript as any).export = exportValue;
272
+ }
262
273
 
263
274
  // Append to this element's children
264
275
  this.appendChild(clonedScript);
@@ -152,8 +152,8 @@ export class EMCScriptHandler extends EvtRt {
152
152
  if (!enh) {
153
153
  throw new Error('Element does not have enh property. Make sure ElementMountExtension is loaded.');
154
154
  }
155
- // Pass synthesizerElement through SpawnContext if available
156
- const spawnContext = synthesizerElement ? { synthesizerElement } : undefined;
155
+ // Pass synthesizerElement and full EMC config through SpawnContext
156
+ const spawnContext = { synthesizerElement, emc: emcConfig };
157
157
  await enh.get(enhancementConfig, spawnContext);
158
158
  }
159
159
  /**
@@ -180,8 +180,8 @@ export class EMCScriptHandler extends EvtRt {
180
180
  throw new Error('Element does not have enh property. Make sure ElementMountExtension is loaded.');
181
181
  }
182
182
 
183
- // Pass synthesizerElement through SpawnContext if available
184
- const spawnContext = synthesizerElement ? { synthesizerElement } : undefined;
183
+ // Pass synthesizerElement and full EMC config through SpawnContext
184
+ const spawnContext = { synthesizerElement, emc: emcConfig };
185
185
  await enh.get(enhancementConfig, spawnContext);
186
186
  }
187
187
 
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "mount-observer",
3
- "version": "0.1.34",
3
+ "version": "0.1.36",
4
4
  "description": "Observe and act on css matches.",
5
5
  "main": "MountObserver.js",
6
6
  "module": "MountObserver.js",
7
7
  "dependencies": {
8
- "assign-gingerly": "0.0.30",
8
+ "assign-gingerly": "0.0.38",
9
9
  "id-generation": "0.0.4"
10
10
  },
11
11
  "devDependencies": {
@@ -0,0 +1,11 @@
1
+ import {RAConfig} from '../roundabout/types';
2
+ import {AttrPatterns} from '../assign-gingerly/types';
3
+
4
+ /**
5
+ * Assign Gingerly Roundabout Config
6
+ */
7
+ export interface AgraceConfig<TProps = unknown, TActions = TProps, ETProps = TProps, TCustomData = unknown> {
8
+ raConfig: RAConfig<TProps, TActions, ETProps, TCustomData>,
9
+ withAttrs?: AttrPatterns<TProps>,
10
+ template?: string | HTMLTemplateElement,
11
+ }
@@ -212,6 +212,13 @@ export interface SpawnContext<T = any, TMountContext = any> {
212
212
  * Used for scoped parser registry access during attribute parsing.
213
213
  */
214
214
  synthesizerElement?: Element;
215
+ /**
216
+ * The full EMC configuration object that triggered this spawn.
217
+ * Passed through so enhancement classes can access their full configuration
218
+ * (including customData) without needing to separately import the JSON file.
219
+ * This avoids duplicate JSON imports when using emoji shorthand aliases.
220
+ */
221
+ emc?: any;
215
222
  }
216
223
 
217
224
  /**
@@ -226,6 +233,14 @@ export interface IAssignGingerlyOptions {
226
233
  registry?: typeof EnhancementRegistry | EnhancementRegistry;
227
234
  bypassChecks?: boolean;
228
235
  withMethods?: string[] | Set<string>;
236
+ aka?: Record<string, string>;
237
+
238
+ /**
239
+ * AbortSignal for cleaning up reactive subscriptions (@eachTime)
240
+ * Required when using @eachTime symbol for reactive iteration
241
+ * When the signal is aborted, all event listeners are automatically removed
242
+ */
243
+ signal?: AbortSignal;
229
244
  }
230
245
 
231
246
  /**
@@ -242,7 +257,6 @@ export declare class EnhancementRegisteredEvent extends Event {
242
257
  * Extends EventTarget to dispatch events when configs are registered
243
258
  */
244
259
  export declare class EnhancementRegistry extends EventTarget {
245
- private items;
246
260
  push(items: EnhancementConfig | EnhancementConfig[]): void;
247
261
  getItems(): EnhancementConfig[];
248
262
  findBySymbol(symbol: symbol | string): EnhancementConfig | undefined;
@@ -303,10 +317,7 @@ export declare class ElementEnhancementGateway{
303
317
  }
304
318
 
305
319
  export interface ElementEnhancement{
306
- dispose(regItem: EnhancementConfig): void;
307
- }
308
-
309
- export interface ElementInfer{
310
- value: any;
311
- eventType: string
320
+ get(registryItem: EnhancementConfig | string | symbol, mountCtx?: any): any;
321
+ dispose(registryItem: EnhancementConfig | string | symbol): void;
322
+ whenResolved(registryItem: EnhancementConfig | string | symbol, mountCtx?: any): Promise<any>;
312
323
  }
@@ -19,7 +19,8 @@ export interface BindingRule {
19
19
 
20
20
  localProp?: string,
21
21
  localEvent?: string,
22
- remoteSpecifierString?: string,
22
+ remoteId?: string,
23
+ remoteProp?: string,
23
24
  remoteSpecifier?: Specifier,
24
25
 
25
26
 
@@ -1,4 +1,4 @@
1
- import { ElementEnhancementGateway } from "../assign-gingerly/types";
1
+ import { ElementEnhancementGateway, SpawnContext } from "../assign-gingerly/types";
2
2
  import { StatementsResult } from "../nested-regex-groups/types";
3
3
 
4
4
  export interface Specifier {
@@ -23,7 +23,7 @@ export type ProPAP = Promise<PAP>
23
23
 
24
24
  export interface Actions{
25
25
  hydrate(self: AP): ProPAP;
26
- init(self: AP, enhancedElement: Element, initVals: PAP): Promise<void>
26
+ init(self: AP, enhancedElement: Element, ctx: SpawnContext, initVals: PAP): Promise<void>
27
27
  }
28
28
 
29
29
 
@@ -1,4 +1,4 @@
1
- import { ElementEnhancementGateway, ElementInfer } from "../assign-gingerly/types";
1
+ import { ElementEnhancementGateway } from "../assign-gingerly/types";
2
2
  import { StatementsResult } from "../nested-regex-groups/types";
3
3
 
4
4
  export interface EndUserProps{}
@@ -0,0 +1,46 @@
1
+ import type { EnhancementConfig } from "../assign-gingerly/types";
2
+
3
+ /**
4
+ * Symbol for smart value assignment
5
+ */
6
+ export declare const value: symbol;
7
+
8
+ /**
9
+ * Symbol for smart display assignment
10
+ */
11
+ export declare const display: symbol;
12
+
13
+ /**
14
+ * Enhancement class that provides smart value and display property inference
15
+ */
16
+ export declare class Infer<TValue = any, TDisplay = any> {
17
+ get enhancedElement(): Element;
18
+ constructor(enhancedElement?: Element);
19
+ get value(): TValue | undefined;
20
+ set value(nv: TValue);
21
+ get display(): TDisplay | undefined;
22
+ set display(nv: TDisplay);
23
+ get eventType(): string;
24
+ }
25
+
26
+ /**
27
+ * Registry item for the Infer enhancement
28
+ */
29
+ export declare const registryItem: EnhancementConfig;
30
+
31
+ /**
32
+ * Infer the most appropriate value property for an element
33
+ */
34
+ export declare function inferValueProperty(element: Element): string;
35
+
36
+ /**
37
+ * Infer the most appropriate display property for an element
38
+ */
39
+ export declare function inferDisplayProperty(element: Element): string;
40
+
41
+ /**
42
+ * Infer the most appropriate event type for an element
43
+ */
44
+ export declare function inferEventType(element: Element): string;
45
+
46
+ export default registryItem;
@@ -1,6 +1,6 @@
1
1
  // Core types for MountObserver v2 - Polyfill Supported Scenario I
2
2
 
3
- import {Spawner, EnhancementConfigBase, EnhKey, AttrPatterns} from '../assign-gingerly/types';
3
+ import {EnhancementConfigBase, EnhKey, AttrPatterns} from '../assign-gingerly/types';
4
4
 
5
5
  export type Constructor = new (...args: any[]) => any;
6
6
 
@@ -24,11 +24,17 @@ export interface LogicOp<Props = any, TActions = Props>{
24
24
 
25
25
  delay?: number,
26
26
 
27
+ }
28
+
29
+ /**
30
+ * Extends LogicOp with a `do` property for specifying which function to call.
31
+ * Used by positractions where the function is generic and view-model-neutral.
32
+ */
33
+ export interface LogicOpWithDo<Props = any, TActions = Props> extends LogicOp<Props, TActions>{
27
34
  do?:
28
35
  | Function
29
36
  | (keyof TActions & string)
30
37
  | PropsToProps<Props>
31
-
32
38
  }
33
39
 
34
40
  export type Actions<TProps = any, TActions = TProps> =
@@ -46,6 +52,8 @@ export type Compacts<TProps = any, TActions = TProps> =
46
52
  | Partial<{[key in `when_${keyof TProps & string}_changes_toggle_${keyof TProps & string}`]: number}>
47
53
  | Partial<{[key in `when_${keyof TProps & string}_changes_inc_${keyof TProps & string}_by`]: number}>
48
54
  | Partial<{[key in `when_${keyof TProps & string}_changes_dispatch`]: string}> //TODO
55
+ | Partial<{[key in `on_${string}_of_${keyof TProps & string}_inc_${keyof TProps & string}_by`]: number}>
56
+ | Partial<{[key in `on_${string}_of_${keyof TProps & string}_set_${keyof TProps & string}_to`]: any}>
49
57
  ;
50
58
 
51
59
  export type Hitches<TProps = any, TActions = TProps> =
@@ -58,7 +66,7 @@ export type Handlers<ETProps = any, TActions = ETProps> =
58
66
  export type Positractions<TProps = any, TActions = TProps> =
59
67
  | Array<Positraction<TProps, TActions>>;
60
68
 
61
- export interface Positraction<TProps = any, TActions = TProps> extends LogicOp<TProps, TActions> {
69
+ export interface Positraction<TProps = any, TActions = TProps> extends LogicOpWithDo<TProps, TActions> {
62
70
  do:
63
71
  | Function
64
72
  | (keyof TActions & string)
@@ -71,13 +79,30 @@ export interface Positraction<TProps = any, TActions = TProps> extends LogicOp<T
71
79
  assignTo?: Array<null | (keyof TProps & string)>
72
80
  }
73
81
 
82
+ /**
83
+ * A merge is a fully JSON-serializable reactive rule.
84
+ * When its conditions are met, it calls assignFrom(vm, assignFrom, { from: vm })
85
+ * to resolve RHS path strings against the vm and assign the results into the vm.
86
+ * No method or code is required.
87
+ */
88
+ export interface Merge<TProps = any> extends LogicOp<TProps> {
89
+ /**
90
+ * Pattern object whose keys are LHS assignGingerly paths and whose
91
+ * values are RHS `?.`-prefixed path strings resolved against the vm.
92
+ */
93
+ assign: Record<string, any>;
94
+ }
95
+
96
+ export type Merges<TProps = any> = Array<Merge<TProps>>;
97
+
74
98
  export interface RAConfig<TProps = unknown, TActions = TProps, ETProps = TProps, TCustomData = unknown> {
75
99
  actions?: Actions<TProps,TActions>,
76
100
  compacts?: Compacts<TProps, TActions>,
77
101
  //onsets?: Onsets<TProps, TActions>,
78
102
  handlers?: Handlers<ETProps, TActions>,
79
- hitch?: Hitches<TProps, TActions>,
103
+ hitches?: Hitches<TProps, TActions>,
80
104
  positractions?: Positractions<TProps>,
105
+ merges?: Merges<TProps>,
81
106
  /**
82
107
  * Configure automatic WeakRef wrapping for properties
83
108
  *
@@ -128,6 +153,12 @@ export interface RoundaboutOptions<TProps = unknown, TActions = TProps, ETProps
128
153
  * - Diamond dependencies (A→B, A→C, B→D, C→D)
129
154
  */
130
155
  internalRouting?: boolean,
156
+
157
+ /**
158
+ * Options passed to every internal assignGingerly call.
159
+ * See IAssignGingerlyOptions in assign-gingerly for details.
160
+ */
161
+ assignGingerlyOptions?: import('../assign-gingerly/types.js').IAssignGingerlyOptions,
131
162
 
132
163
 
133
164
  }