assign-gingerly 0.0.64 → 0.0.66

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.
Files changed (42) hide show
  1. package/README.md +85 -26
  2. package/assignFrom.js +21 -19
  3. package/assignFrom.ts +28 -25
  4. package/assignFromAsync.js +10 -7
  5. package/assignFromAsync.ts +15 -98
  6. package/assignGingerly.js +54 -26
  7. package/assignGingerly.ts +62 -27
  8. package/assignTentatively.js +8 -0
  9. package/assignTentatively.ts +6 -0
  10. package/{builtInEmoji.ts → emojis.js} +46 -34
  11. package/emojis.ts +52 -0
  12. package/getValues.js +80 -25
  13. package/getValues.ts +85 -26
  14. package/handlers/addEventListener.js +153 -0
  15. package/handlers/addEventListener.ts +178 -0
  16. package/handlers/arr.js +13 -0
  17. package/handlers/arr.ts +13 -0
  18. package/handlers/lazyLoad.js +3 -3
  19. package/handlers/lazyLoad.ts +3 -3
  20. package/handlers/manageTemplateList.js +48 -21
  21. package/handlers/manageTemplateList.ts +51 -21
  22. package/handlers/nudge.js +23 -0
  23. package/handlers/nudge.ts +23 -0
  24. package/index.js +2 -0
  25. package/index.ts +2 -0
  26. package/inferencer/types/assign-gingerly/types.d.ts +327 -1
  27. package/inferencer/types/mount-observer/types.d.ts +10 -2
  28. package/inferencer/types/roundabout/types.d.ts +1 -1
  29. package/inferencer/types/three-peat/types.d.ts +18 -0
  30. package/object-extension.js +1 -1
  31. package/package.json +12 -4
  32. package/paths.ts +1 -1
  33. package/{withIdsCorrector.js → pinCorrector.js} +5 -5
  34. package/{withIdsCorrector.ts → pinCorrector.ts} +5 -5
  35. package/processHandlerCommands.js +4 -2
  36. package/processHandlerCommands.ts +4 -2
  37. package/resolveIdRef.js +8 -8
  38. package/resolveIdRef.ts +9 -9
  39. package/resolveValues.js +20 -88
  40. package/resolveValues.ts +17 -91
  41. package/types/assign-gingerly/types.d.ts +159 -3
  42. package/builtInEmoji.js +0 -26
@@ -22,117 +22,31 @@
22
22
  import { resolveValues } from './resolveValues.js';
23
23
  import assignGingerly, { IAssignGingerlyOptions } from './assignGingerly.js';
24
24
  import type { AssignPermissions } from './isAllowedImportPath.js';
25
+ import type { AssignFromHandler, AssignFromHandlerConstructor } from './types/assign-gingerly/types.js';
25
26
  import {
26
27
  expandSubstitutions, categorizeKeys, handleSpreads, isHandlerCommand
27
28
  } from './assignFrom.js';
28
29
 
29
30
  export interface AssignFromOptions extends IAssignGingerlyOptions {
30
- /** Source object to resolve RHS path strings against */
31
31
  from: any;
32
-
33
- /** Protocol handlers (sync or async) */
34
32
  protocols?: Record<string, (key: string) => any | Promise<any>>;
35
-
36
- /** Loop variable bindings — expand pattern entries containing ${x} */
37
33
  where_x_in?: string[];
38
- /** Loop variable bindings — expand pattern entries containing ${y} */
39
34
  where_y_in?: string[];
40
- /** Loop variable bindings — expand pattern entries containing ${z} */
41
35
  where_z_in?: string[];
42
-
43
- /**
44
- * Cached element references by variable name.
45
- * Used with `#[varName]` syntax in LHS keys for fast repeated element access.
46
- *
47
- * - String value: existing element ID (uses getElementById)
48
- * - Object value: { qry: 'selector' } — finds element via querySelector on target, auto-assigns an ID
49
- *
50
- * Elements are cached via WeakRef with getElementById fallback on cache miss.
51
- */
52
- withIds?: Record<string, string | { qry: string }>;
53
-
54
- /**
55
- * Positional element references for use with `#[varName]` syntax.
56
- * Resolves elements by child index path — no IDs assigned, no caching.
57
- *
58
- * - Array value: child index path (e.g., [0, 1] = target.children[0].children[1])
59
- * - Object value: { path: [...], expect?: 'selector', fallback?: true }
60
- * expect: validates via element.matches(), logs correction if wrong
61
- * fallback: on mismatch, recovers via querySelector(expect)
62
- */
36
+ pin?: Record<string, string | { qry: string } | { path: number[]; expect?: string; fallback?: boolean }>;
63
37
  at?: Record<string, number[] | { path: number[]; expect?: string; fallback?: boolean }>;
64
-
65
- /**
66
- * Handler implementations scoped to this call.
67
- * Key: the `do` name referenced in handler configs.
68
- * Value: a class constructor, or an import path to dynamically load one.
69
- *
70
- * Import paths must be local (relative, absolute, or bare specifier — no cross-domain URLs).
71
- * The module's default export is checked first; otherwise the first exported class
72
- * with an `assign` method on its prototype is used.
73
- *
74
- * Built-in handlers (builtIns.*) auto-load without needing to be listed here.
75
- *
76
- * @example
77
- * handlers: {
78
- * 'my-list': MyListHandler, // class constructor
79
- * 'my-chart': './handlers/chart.js', // dynamic import path
80
- * 'vendor-widget': 'some-package/handler.js', // bare specifier (import map)
81
- * }
82
- */
83
38
  handlers?: Record<string, AssignFromHandlerConstructor | string>;
84
-
85
- /**
86
- * Inferred assignments — automatically distribute source values to matching
87
- * DOM elements based on structural conventions (itemprop, name, etc.).
88
- *
89
- * Uses the inferencer submodule to determine the correct property for each
90
- * matched element (textContent, value, checked, dateTime, ish, etc.).
91
- *
92
- * @example
93
- * infer: {
94
- * byItemprop: ['user', 'name', 'email'], // or true for all source keys
95
- * beVigilant: true, // watch for new matching elements (requires signal)
96
- * }
97
- */
98
39
  infer?: {
99
40
  byItemprop?: string[] | true;
100
41
  '|'?: string[] | true;
101
42
  byName?: string[] | true | { props: string[] | true; outside: string };
102
43
  '@'?: string[] | true | { props: string[] | true; outside: string };
103
- /** Watch for new matching elements via MutationObserver. Requires options.signal for cleanup. */
104
44
  beVigilant?: boolean;
105
45
  };
106
-
107
- /**
108
- * Bulk enhancement application via EMC JSON configs.
109
- * Finds matching elements and spawns enhancements on them.
110
- *
111
- * Each entry specifies an EMC JSON path and optionally overrides the matching selector.
112
- * Enhancements are auto-registered if not already present in the enhancement registry.
113
- *
114
- * No scope perimeter is applied — use mount-observer for reactive/scoped enhancement.
115
- *
116
- * @example
117
- * enhance: [
118
- * { emc: 'be-bound/emc.json', matching: '[name]' },
119
- * { emc: 'be-observant/emc.json', matching: '[itemprop]' },
120
- * ]
121
- */
122
46
  enhance?: Array<{ emc: string; matching?: string; parse?: boolean }>;
123
47
  }
124
48
 
125
- /**
126
- * Interface for assignFrom handler classes.
127
- * Handlers are invoked when a LHS key ends with ' =>'.
128
- */
129
- export interface AssignFromHandler {
130
- assign(lhsTarget: any, resolvedParams: Record<string, any>, options: AssignFromOptions): Promise<void> | void;
131
- }
132
-
133
- export interface AssignFromHandlerConstructor {
134
- new (config: any): AssignFromHandler;
135
- }
49
+ export type { AssignFromHandler, AssignFromHandlerConstructor };
136
50
 
137
51
  // Module cache for processHandlerCommands — avoids await on dynamic import after first call
138
52
  let _processHandlerCommands: any;
@@ -154,7 +68,9 @@ export async function assignFromAsync(
154
68
  const resolved = await resolveValues(normalPattern, options.from, {
155
69
  withMethods: options.withMethods,
156
70
  aka: options.aka,
157
- protocols: options.protocols
71
+ akaMethods: options.akaMethods,
72
+ protocols: options.protocols,
73
+ root: target
158
74
  });
159
75
 
160
76
  // Recursively handle "..." spread keys at all nesting levels
@@ -164,9 +80,10 @@ export async function assignFromAsync(
164
80
  }
165
81
 
166
82
  // Process #[x] normal keys — resolve element, then apply remaining path + value
167
- if (idRefNormalKeys.length > 0 && (options.withIds || options.at)) {
168
- const ids = { ...options.withIds, ...options.at };
83
+ if (idRefNormalKeys.length > 0 && (options.pin || options.at)) {
84
+ const ids = { ...options.pin, ...options.at };
169
85
  const { resolveIdVariable, parseIdRef } = await import('./resolveIdRef.js');
86
+ const { withMethods, aka, akaMethods, protocols, from } = options;
170
87
  for (const key of idRefNormalKeys) {
171
88
  const parsed = parseIdRef(key);
172
89
  if (!parsed) continue;
@@ -178,8 +95,8 @@ export async function assignFromAsync(
178
95
  if (parsed.remainingPath) {
179
96
  // Resolve the RHS value
180
97
  const resolvedValue = await resolveValues(
181
- { __v: value }, options.from,
182
- { withMethods: options.withMethods, aka: options.aka, protocols: options.protocols }
98
+ { __v: value }, from,
99
+ { withMethods, aka, akaMethods, protocols, root: el }
183
100
  );
184
101
  // Apply remaining path on the resolved element
185
102
  assignGingerly(el, { [parsed.remainingPath]: resolvedValue.__v }, options);
@@ -187,8 +104,8 @@ export async function assignFromAsync(
187
104
  // No remaining path — resolve and assign directly to the element
188
105
  const resolvedValue = await resolveValues(
189
106
  typeof value === 'object' && value !== null ? value : { __v: value },
190
- options.from,
191
- { withMethods: options.withMethods, aka: options.aka, protocols: options.protocols }
107
+ from,
108
+ { withMethods, aka, akaMethods, protocols, root: el }
192
109
  );
193
110
  if ('__v' in resolvedValue) {
194
111
  // Single value — can't assign to element root without a path
@@ -205,8 +122,8 @@ export async function assignFromAsync(
205
122
  await _processHandlerCommands(target, handlerKeys, expandedPattern, options, permissions);
206
123
  }
207
124
  // Process #[x] handler keys — resolve element, then pass to handler processing
208
- if (idRefHandlerKeys.length > 0 && (options.withIds || options.at)) {
209
- const ids = { ...options.withIds, ...options.at };
125
+ if (idRefHandlerKeys.length > 0 && (options.pin || options.at)) {
126
+ const ids = { ...options.pin, ...options.at };
210
127
  const { resolveIdVariable, parseIdRef } = await import('./resolveIdRef.js');
211
128
  _processHandlerCommands ??= (await import('./processHandlerCommands.js')).processHandlerCommands;
212
129
 
package/assignGingerly.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { normalizeAliasOptions } from './getValues.js';
1
2
  /**
2
3
  * GUID for global instance map storage to ensure uniqueness across package versions
3
4
  */
@@ -561,29 +562,13 @@ export function assignGingerly(target, source, options, permissions) {
561
562
  if (!target || typeof target !== 'object') {
562
563
  return target;
563
564
  }
564
- // Convert withMethods array to Set for O(1) lookup
565
- const withMethodsSet = options?.withMethods
566
- ? options.withMethods instanceof Set
567
- ? options.withMethods
568
- : new Set(options.withMethods)
569
- : undefined;
565
+ const { aliasMap, withMethods: withMethodsSet } = normalizeAliasOptions(options);
570
566
  // Convert withAsyncMethods array to Set for O(1) lookup
571
567
  const withAsyncMethodsSet = options?.withAsyncMethods
572
568
  ? options.withAsyncMethods instanceof Set
573
569
  ? options.withAsyncMethods
574
570
  : new Set(options.withAsyncMethods)
575
571
  : undefined;
576
- // Convert aka object to Map for O(1) lookup and validate aliases
577
- const aliasMap = new Map();
578
- if (options?.aka) {
579
- for (const [alias, target] of Object.entries(options.aka)) {
580
- // Validate: disallow space and backtick in aliases
581
- if (alias.includes(' ') || alias.includes('`')) {
582
- throw new Error(`Invalid alias '${alias}': aliases cannot contain space or backtick characters`);
583
- }
584
- aliasMap.set(alias, target);
585
- }
586
- }
587
572
  const registry = options?.registry instanceof EnhancementRegistry
588
573
  ? options.registry
589
574
  : options?.registry
@@ -653,22 +638,61 @@ export function assignGingerly(target, source, options, permissions) {
653
638
  if (path) {
654
639
  if (isNestedPath(path)) {
655
640
  const pathParts = parsePath(path);
656
- const lastKey = pathParts[pathParts.length - 1];
657
- const parent = ensureNestedPath(target, pathParts);
658
- if (!(lastKey in parent)) {
659
- parent[lastKey] = value;
641
+ // Check for withMethods path evaluation
642
+ let lhsValue;
643
+ let lhsParent;
644
+ let lhsKey;
645
+ if (withMethodsSet) {
646
+ const result = evaluatePathWithMethods(target, pathParts, value, withMethodsSet);
647
+ lhsParent = result.target;
648
+ lhsKey = result.lastKey;
649
+ lhsValue = lhsParent[lhsKey];
660
650
  }
661
- else if (Array.isArray(parent[lastKey])) {
662
- parent[lastKey] = Array.isArray(value)
663
- ? [...parent[lastKey], ...value]
664
- : [...parent[lastKey], value];
651
+ else {
652
+ lhsKey = pathParts[pathParts.length - 1];
653
+ lhsParent = ensureNestedPath(target, pathParts);
654
+ lhsValue = lhsParent[lhsKey];
655
+ }
656
+ // Event handler: Element LHS + object RHS with 'on' property
657
+ if (lhsValue instanceof Element && value && typeof value === 'object' && !Array.isArray(value) && 'on' in value) {
658
+ const capturedLhs = lhsValue;
659
+ const capturedValue = value;
660
+ const capturedTarget = target;
661
+ const capturedOptions = options;
662
+ import('./handlers/addEventListener.js').then(({ attachEventListener }) => {
663
+ attachEventListener(capturedLhs, capturedValue, capturedTarget, capturedOptions?.from ?? capturedTarget, capturedOptions ?? {});
664
+ });
665
+ continue;
666
+ }
667
+ if (!(lhsKey in lhsParent)) {
668
+ lhsParent[lhsKey] = value;
669
+ }
670
+ else if (Array.isArray(lhsValue)) {
671
+ lhsParent[lhsKey] = Array.isArray(value)
672
+ ? [...lhsValue, ...value]
673
+ : [...lhsValue, value];
674
+ }
675
+ else if (typeof lhsValue === 'number' && typeof value === 'string') {
676
+ const parsed = Number(value);
677
+ lhsParent[lhsKey] = isNaN(parsed) ? lhsValue + value : lhsValue + parsed;
665
678
  }
666
679
  else {
667
- parent[lastKey] += value;
680
+ lhsParent[lhsKey] += value;
668
681
  }
669
682
  }
670
683
  else {
671
684
  // Plain key - direct operation on target
685
+ // Event handler: Element LHS + object RHS with 'on' property
686
+ if (target[path] instanceof Element && value && typeof value === 'object' && !Array.isArray(value) && 'on' in value) {
687
+ const capturedLhs = target[path];
688
+ const capturedValue = value;
689
+ const capturedTarget = target;
690
+ const capturedOptions = options;
691
+ import('./handlers/addEventListener.js').then(({ attachEventListener }) => {
692
+ attachEventListener(capturedLhs, capturedValue, capturedTarget, capturedOptions?.from ?? capturedTarget, capturedOptions ?? {});
693
+ });
694
+ continue;
695
+ }
672
696
  if (!(path in target)) {
673
697
  target[path] = value;
674
698
  }
@@ -677,6 +701,10 @@ export function assignGingerly(target, source, options, permissions) {
677
701
  ? [...target[path], ...value]
678
702
  : [...target[path], value];
679
703
  }
704
+ else if (typeof target[path] === 'number' && typeof value === 'string') {
705
+ const parsed = Number(value);
706
+ target[path] = isNaN(parsed) ? target[path] + value : target[path] + parsed;
707
+ }
680
708
  else {
681
709
  target[path] += value;
682
710
  }
package/assignGingerly.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  import { EnhancementConfig } from "./types/assign-gingerly/types";
4
4
  import type { FeatureConfigsMap } from "./types/assign-gingerly/types";
5
5
  import type { AssignPermissions } from "./isAllowedImportPath.js";
6
+ import { normalizeAliasOptions } from './getValues.js';
6
7
 
7
8
  /**
8
9
  * Constructor signature for ItemScope Manager classes
@@ -82,6 +83,13 @@ export interface IAssignGingerlyOptions {
82
83
  * // Equivalent to: element.querySelector('my-element').classList.add('highlighted')
83
84
  */
84
85
  aka?: Record<string, string>;
86
+
87
+ /**
88
+ * Shorthand for binding method aliases from the source object.
89
+ * Each entry maps an alias to a method name, and is normalized into
90
+ * the existing withMethods + aka behavior.
91
+ */
92
+ akaMethods?: Record<string, string>;
85
93
 
86
94
  /**
87
95
  * AbortSignal for cleaning up reactive subscriptions (@eachTime)
@@ -760,12 +768,7 @@ export function assignGingerly(
760
768
  return target;
761
769
  }
762
770
 
763
- // Convert withMethods array to Set for O(1) lookup
764
- const withMethodsSet = options?.withMethods
765
- ? options.withMethods instanceof Set
766
- ? options.withMethods
767
- : new Set(options.withMethods)
768
- : undefined;
771
+ const { aliasMap, withMethods: withMethodsSet } = normalizeAliasOptions(options);
769
772
 
770
773
  // Convert withAsyncMethods array to Set for O(1) lookup
771
774
  const withAsyncMethodsSet = options?.withAsyncMethods
@@ -774,18 +777,6 @@ export function assignGingerly(
774
777
  : new Set(options.withAsyncMethods)
775
778
  : undefined;
776
779
 
777
- // Convert aka object to Map for O(1) lookup and validate aliases
778
- const aliasMap = new Map<string, string>();
779
- if (options?.aka) {
780
- for (const [alias, target] of Object.entries(options.aka)) {
781
- // Validate: disallow space and backtick in aliases
782
- if (alias.includes(' ') || alias.includes('`')) {
783
- throw new Error(`Invalid alias '${alias}': aliases cannot contain space or backtick characters`);
784
- }
785
- aliasMap.set(alias, target);
786
- }
787
- }
788
-
789
780
  const registry = options?.registry instanceof EnhancementRegistry
790
781
  ? options.registry
791
782
  : options?.registry
@@ -860,25 +851,69 @@ export function assignGingerly(
860
851
  if (path) {
861
852
  if (isNestedPath(path)) {
862
853
  const pathParts = parsePath(path);
863
- const lastKey = pathParts[pathParts.length - 1];
864
- const parent = ensureNestedPath(target, pathParts);
865
- if (!(lastKey in parent)) {
866
- parent[lastKey] = value;
867
- } else if (Array.isArray(parent[lastKey])) {
868
- parent[lastKey] = Array.isArray(value)
869
- ? [...parent[lastKey], ...value]
870
- : [...parent[lastKey], value];
854
+
855
+ // Check for withMethods path evaluation
856
+ let lhsValue: any;
857
+ let lhsParent: any;
858
+ let lhsKey: string;
859
+ if (withMethodsSet) {
860
+ const result = evaluatePathWithMethods(target, pathParts, value, withMethodsSet);
861
+ lhsParent = result.target;
862
+ lhsKey = result.lastKey;
863
+ lhsValue = lhsParent[lhsKey];
871
864
  } else {
872
- parent[lastKey] += value;
865
+ lhsKey = pathParts[pathParts.length - 1];
866
+ lhsParent = ensureNestedPath(target, pathParts);
867
+ lhsValue = lhsParent[lhsKey];
868
+ }
869
+
870
+ // Event handler: Element LHS + object RHS with 'on' property
871
+ if (lhsValue instanceof Element && value && typeof value === 'object' && !Array.isArray(value) && 'on' in value) {
872
+ const capturedLhs = lhsValue;
873
+ const capturedValue = value;
874
+ const capturedTarget = target;
875
+ const capturedOptions = options;
876
+ import('./handlers/addEventListener.js').then(({ attachEventListener }) => {
877
+ attachEventListener(capturedLhs, capturedValue, capturedTarget, capturedOptions?.from ?? capturedTarget, capturedOptions ?? {});
878
+ });
879
+ continue;
880
+ }
881
+
882
+ if (!(lhsKey in lhsParent)) {
883
+ lhsParent[lhsKey] = value;
884
+ } else if (Array.isArray(lhsValue)) {
885
+ lhsParent[lhsKey] = Array.isArray(value)
886
+ ? [...lhsValue, ...value]
887
+ : [...lhsValue, value];
888
+ } else if (typeof lhsValue === 'number' && typeof value === 'string') {
889
+ const parsed = Number(value);
890
+ lhsParent[lhsKey] = isNaN(parsed) ? lhsValue + value : lhsValue + parsed;
891
+ } else {
892
+ lhsParent[lhsKey] += value;
873
893
  }
874
894
  } else {
875
895
  // Plain key - direct operation on target
896
+ // Event handler: Element LHS + object RHS with 'on' property
897
+ if (target[path] instanceof Element && value && typeof value === 'object' && !Array.isArray(value) && 'on' in value) {
898
+ const capturedLhs = target[path];
899
+ const capturedValue = value;
900
+ const capturedTarget = target;
901
+ const capturedOptions = options;
902
+ import('./handlers/addEventListener.js').then(({ attachEventListener }) => {
903
+ attachEventListener(capturedLhs, capturedValue, capturedTarget, capturedOptions?.from ?? capturedTarget, capturedOptions ?? {});
904
+ });
905
+ continue;
906
+ }
907
+
876
908
  if (!(path in target)) {
877
909
  target[path] = value;
878
910
  } else if (Array.isArray(target[path])) {
879
911
  target[path] = Array.isArray(value)
880
912
  ? [...target[path], ...value]
881
913
  : [...target[path], value];
914
+ } else if (typeof target[path] === 'number' && typeof value === 'string') {
915
+ const parsed = Number(value);
916
+ target[path] = isNaN(parsed) ? target[path] + value : target[path] + parsed;
882
917
  } else {
883
918
  target[path] += value;
884
919
  }
@@ -129,6 +129,10 @@ export function assignTentatively(target, source, options) {
129
129
  ? [...parent[lastKey], ...value]
130
130
  : [...parent[lastKey], value];
131
131
  }
132
+ else if (typeof parent[lastKey] === 'number' && typeof value === 'string') {
133
+ const parsed = Number(value);
134
+ parent[lastKey] = isNaN(parsed) ? parent[lastKey] + value : parent[lastKey] + parsed;
135
+ }
132
136
  else {
133
137
  parent[lastKey] += value;
134
138
  }
@@ -149,6 +153,10 @@ export function assignTentatively(target, source, options) {
149
153
  ? [...target[path], ...value]
150
154
  : [...target[path], value];
151
155
  }
156
+ else if (typeof target[path] === 'number' && typeof value === 'string') {
157
+ const parsed = Number(value);
158
+ target[path] = isNaN(parsed) ? target[path] + value : target[path] + parsed;
159
+ }
152
160
  else {
153
161
  target[path] += value;
154
162
  }
@@ -155,6 +155,9 @@ export function assignTentatively(
155
155
  parent[lastKey] = Array.isArray(value)
156
156
  ? [...parent[lastKey], ...value]
157
157
  : [...parent[lastKey], value];
158
+ } else if (typeof parent[lastKey] === 'number' && typeof value === 'string') {
159
+ const parsed = Number(value);
160
+ parent[lastKey] = isNaN(parsed) ? parent[lastKey] + value : parent[lastKey] + parsed;
158
161
  } else {
159
162
  parent[lastKey] += value;
160
163
  }
@@ -172,6 +175,9 @@ export function assignTentatively(
172
175
  target[path] = Array.isArray(value)
173
176
  ? [...target[path], ...value]
174
177
  : [...target[path], value];
178
+ } else if (typeof target[path] === 'number' && typeof value === 'string') {
179
+ const parsed = Number(value);
180
+ target[path] = isNaN(parsed) ? target[path] + value : target[path] + parsed;
175
181
  } else {
176
182
  target[path] += value;
177
183
  }
@@ -1,34 +1,46 @@
1
- /**
2
- * builtInEmoji.ts — Predefined emoji aliases for built-in handlers.
3
- *
4
- * Import and spread into the `handlers` option for concise handler configs:
5
- *
6
- * @example
7
- * import { builtInEmoji } from 'assign-gingerly/builtInEmoji.js';
8
- *
9
- * assignFrom(target, {
10
- * '?.el =>': { do: '🔗', get: { value: ['?.first', ' ', '?.last'] } }
11
- * }, { from: vm, handlers: builtInEmoji });
12
- */
13
-
14
- /**
15
- * Emoji → built-in handler name mapping.
16
- *
17
- * | Emoji | Handler |
18
- * |-------|---------|
19
- * | 📦 | builtIns.lazyLoad |
20
- * | 🎚️ | builtIns.lazyLoadSwitch |
21
- * | 🔗 | builtIns.join |
22
- * | 🏷️ | builtIns.microDataJoin |
23
- * | 📋 | builtIns.manageTemplateList |
24
- */
25
- export const builtInEmoji: Record<string, string> = {
26
- '📦': 'builtIns.lazyLoad',
27
- '🎚️': 'builtIns.lazyLoadSwitch',
28
- '🔗': 'builtIns.join',
29
- '🏷️': 'builtIns.microDataJoin',
30
- '📋': 'builtIns.manageTemplateList',
31
- '📊': 'builtIns.rangeSelector',
32
- };
33
-
34
- export default builtInEmoji;
1
+ /**
2
+ * builtInEmoji.ts — Predefined emoji aliases for built-in handlers.
3
+ *
4
+ * Import and spread into the `handlers` option for concise handler configs:
5
+ *
6
+ * @example
7
+ * import { builtInEmoji } from 'assign-gingerly/builtInEmoji.js';
8
+ *
9
+ * assignFrom(target, {
10
+ * '?.el =>': { do: '🔗', get: { value: ['?.first', ' ', '?.last'] } }
11
+ * }, { from: vm, handlers: builtInEmoji });
12
+ */
13
+ /**
14
+ * Emoji → built-in handler name mapping.
15
+ *
16
+ * | Emoji | Handler |
17
+ * |-------|---------|
18
+ * | 📦 | builtIns.lazyLoad |
19
+ * | 🎚️ | builtIns.lazyLoadSwitch |
20
+ * | 🔗 | builtIns.join |
21
+ * | 🏷️ | builtIns.microDataJoin |
22
+ * | 📋 | builtIns.manageTemplateList |
23
+ */
24
+ export const builtInEmoji = {
25
+ '📦': 'builtIns.lazyLoad',
26
+ '🎚️': 'builtIns.lazyLoadSwitch',
27
+ '🔗': 'builtIns.join',
28
+ '🏷️': 'builtIns.microDataJoin',
29
+ '📋': 'builtIns.manageTemplateList',
30
+ '📊': 'builtIns.rangeSelector',
31
+ };
32
+ export const akaMethods = {
33
+ '🔍': 'querySelector',
34
+ '🧺': 'querySelectorAll',
35
+ '+': 'add',
36
+ '🧬': 'cloneNode'
37
+ };
38
+ export const aka = {
39
+ '©️': 'content?.cloneNode?.true',
40
+ //'🔎': 'clone?.querySelector'
41
+ };
42
+ export const emojis = {
43
+ builtInEmoji,
44
+ akaMethods,
45
+ };
46
+ export default emojis;
package/emojis.ts ADDED
@@ -0,0 +1,52 @@
1
+ /**
2
+ * builtInEmoji.ts — Predefined emoji aliases for built-in handlers.
3
+ *
4
+ * Import and spread into the `handlers` option for concise handler configs:
5
+ *
6
+ * @example
7
+ * import { builtInEmoji } from 'assign-gingerly/builtInEmoji.js';
8
+ *
9
+ * assignFrom(target, {
10
+ * '?.el =>': { do: '🔗', get: { value: ['?.first', ' ', '?.last'] } }
11
+ * }, { from: vm, handlers: builtInEmoji });
12
+ */
13
+
14
+ /**
15
+ * Emoji → built-in handler name mapping.
16
+ *
17
+ * | Emoji | Handler |
18
+ * |-------|---------|
19
+ * | 📦 | builtIns.lazyLoad |
20
+ * | 🎚️ | builtIns.lazyLoadSwitch |
21
+ * | 🔗 | builtIns.join |
22
+ * | 🏷️ | builtIns.microDataJoin |
23
+ * | 📋 | builtIns.manageTemplateList |
24
+ */
25
+ export const builtInEmoji: Record<string, string> = {
26
+ '📦': 'builtIns.lazyLoad',
27
+ '🎚️': 'builtIns.lazyLoadSwitch',
28
+ '🔗': 'builtIns.join',
29
+ '🏷️': 'builtIns.microDataJoin',
30
+ '📋': 'builtIns.manageTemplateList',
31
+ '📊': 'builtIns.rangeSelector',
32
+ };
33
+
34
+ export const akaMethods: Record<string, string> = {
35
+ '🔍': 'querySelector',
36
+ '🧺': 'querySelectorAll',
37
+ '+': 'add',
38
+ '🧬': 'cloneNode'
39
+ };
40
+
41
+ export const aka: Record<string, string> = {
42
+ '©️': 'content?.cloneNode?.true',
43
+ //'🔎': 'clone?.querySelector'
44
+ };
45
+
46
+
47
+ export const emojis = {
48
+ builtInEmoji,
49
+ akaMethods,
50
+ }
51
+
52
+ export default emojis;