assign-gingerly 0.0.65 → 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.
package/README.md CHANGED
@@ -816,7 +816,7 @@ While we are in the business of passing values of object A into object B, we mig
816
816
 
817
817
  | Operator | Name | Description | Example |
818
818
  |----------|------|-------------|---------|
819
- | ` +=` | Increment | Add to numeric value, concatenate strings, append to arrays | `'count +=': 5` |
819
+ | ` +=` | Increment | Add to numeric, concat strings, append to arrays, or [bind events](docs/event-binding.md) | `'count +=': 5` |
820
820
  | ` =!` | Toggle | Negate a boolean (or any value via `!`) | `'visible =!': '.'` |
821
821
  | ` -=` | Delete | Remove properties from an object | `'?.data -=': 'key'` |
822
822
  | ` Y=` | Merge | Recursively `assignGingerly` into a sub-object | `'style Y=': { width: '100px' }` |
@@ -857,6 +857,8 @@ The `+=` command syntax is `<path> +=` where the path uses the `?.` nested notat
857
857
  | LHS type | RHS type | Result |
858
858
  |----------|----------|--------|
859
859
  | number | number | addition (`2 += 3` → `5`) |
860
+ | number | string (numeric) | parse + addition (`5 += '3'` → `8`) |
861
+ | number | string (non-numeric) | string concatenation (`5 += 'px'` → `'5px'`) |
860
862
  | string | any | string concatenation (`"hello" += 3` → `"hello3"`) |
861
863
  | array | array | array concatenation (`[1,2] += [3,4]` → `[1,2,3,4]`) |
862
864
  | array | non-array | push single item (`[1,2] += 3` → `[1,2,3]`) |
@@ -876,6 +878,22 @@ assignGingerly(obj, {
876
878
  assignGingerly(obj, { '?.tags +=': 'e' }); // ['a', 'b', 'c', 'd', 'e']
877
879
  ```
878
880
 
881
+ **Event binding with `+=`:**
882
+
883
+ When the LHS resolves to a DOM Element and the RHS is an object with an `on` property, `+=` attaches a declarative event listener:
884
+
885
+ ```JavaScript
886
+ assignFrom(this.shadowRoot, {
887
+ '?.querySelector?.button +=': {
888
+ on: 'click',
889
+ '?.isHappy =!': '.', // toggle host property
890
+ fromLHS: { '?.age +=': '?.dataset.diff' } // read from button, assign to host
891
+ }
892
+ }, { from: this, withMethods: ['querySelector'] });
893
+ ```
894
+
895
+ The handler is lazy-loaded on demand. For full details including assignment vectors, dedup, nudge, and custom event dispatch, see [docs/event-binding.md](docs/event-binding.md).
896
+
879
897
  ## Example 5 - Toggling boolean values and negating
880
898
 
881
899
  The `=!` command allows us to toggle boolean values:
@@ -3900,7 +3918,7 @@ await assignFromAsync(container, {
3900
3918
  if: '?.showPanel',
3901
3919
  instantiate: 'globalThis://panelTemplate',
3902
3920
  assign: {
3903
- assignToFragment: {
3921
+ toClone: {
3904
3922
  '#[title]?.textContent': '?.panelTitle',
3905
3923
  '#[body]?.textContent': '?.panelContent'
3906
3924
  },
@@ -3913,7 +3931,7 @@ await assignFromAsync(container, {
3913
3931
  }, { from: vm, withMethods: ['querySelector'], protocols: { globalThis: k => globalThis[k] } });
3914
3932
  ```
3915
3933
 
3916
- The `assign.assignToFragment` paths resolve against `options.from` (the same source that drives the `if` condition). For multi-element templates, use `assign.configs` (same zip semantics as `manageTemplateList`).
3934
+ The `assign.toClone` paths resolve against `options.from` (the same source that drives the `if` condition). For multi-element templates, use `assign.configs` (same zip semantics as `manageTemplateList`).
3917
3935
 
3918
3936
  ### View Transitions
3919
3937
 
@@ -4230,7 +4248,7 @@ assignFrom(document.body, {
4230
4248
  instantiate: 'globalThis://country-ranking',
4231
4249
  },
4232
4250
  fromEachItem: {
4233
- assignToFragment: { '?.querySelector?.tr?.ish': '?.' },
4251
+ toClone: { '?.querySelector?.tr?.ish': '?.' },
4234
4252
  withOptions: { withMethods: ['querySelector'], infer: true },
4235
4253
  get: { key: '?.rank' }
4236
4254
  }
@@ -4246,7 +4264,7 @@ assignFrom(document.body, {
4246
4264
 
4247
4265
  1. Resolves `forEach` (iterable) and `instantiate` (template) from the `resolve` block
4248
4266
  2. Clones the template once per item, buffering all clones into a `DocumentFragment`
4249
- 3. For each clone, calls `assignFrom(clone, assignToFragment, { from: item, ...withOptions })` — distributing the item's data
4267
+ 3. For each clone, calls `assignFrom(clone, toClone, { from: item, ...withOptions })` — distributing the item's data
4250
4268
  4. Inserts the fragment between comment markers in one DOM operation
4251
4269
  5. On subsequent calls, reconciles by `key` — adds new items, removes missing ones, updates existing clones in place
4252
4270
 
@@ -4259,13 +4277,13 @@ The `key` field (in `fromEachItem.get`) identifies each item for stable identity
4259
4277
 
4260
4278
  Without `key`, positional matching is used (item[i] → clone[i]).
4261
4279
 
4262
- **Shared parent data (`fromSource`):**
4280
+ **Shared parent data (`fromHost`):**
4263
4281
 
4264
4282
  Pass data from the outer VM into each clone (e.g., aggregate totals):
4265
4283
 
4266
4284
  ```JavaScript
4267
- fromSource: {
4268
- assignToFragment: {
4285
+ fromHost: {
4286
+ toClone: {
4269
4287
  '?.querySelector?.[part~="totalMedalCount"]?.textContent': '?.totalMedalCount'
4270
4288
  },
4271
4289
  withOptions: { withMethods: ['querySelector'] }
package/assignFrom.js CHANGED
@@ -307,7 +307,7 @@ function processIdRefNormalKeys(idRefNormalKeys, expandedPattern, target, option
307
307
  const ids = getEffectiveIds(options);
308
308
  if (!ids)
309
309
  return;
310
- //TODO
310
+ const { withMethods, aka, akaMethods, protocols, from } = options;
311
311
  for (const key of idRefNormalKeys) {
312
312
  const parsed = parseIdRef(key);
313
313
  if (!parsed)
@@ -317,11 +317,11 @@ function processIdRefNormalKeys(idRefNormalKeys, expandedPattern, target, option
317
317
  continue;
318
318
  const value = expandedPattern[key];
319
319
  if (parsed.remainingPath) {
320
- const resolvedValue = getValues({ __v: value }, options.from, { withMethods: options.withMethods, aka: options.aka, akaMethods: options.akaMethods, protocols: options.protocols, root: target });
320
+ const resolvedValue = getValues({ __v: value }, from, { withMethods, aka, akaMethods, protocols, root: target });
321
321
  assignGingerly(el, { [parsed.remainingPath]: resolvedValue.__v }, options);
322
322
  }
323
323
  else {
324
- const resolvedValue = getValues(typeof value === 'object' && value !== null ? value : { __v: value }, options.from, { withMethods: options.withMethods, aka: options.aka, akaMethods: options.akaMethods, protocols: options.protocols, root: target });
324
+ const resolvedValue = getValues(typeof value === 'object' && value !== null ? value : { __v: value }, from, { withMethods, aka, akaMethods, protocols, root: target });
325
325
  if (!('__v' in resolvedValue)) {
326
326
  assignGingerly(el, resolvedValue, options);
327
327
  }
package/assignFrom.ts CHANGED
@@ -321,7 +321,8 @@ function processIdRefNormalKeys(
321
321
  ): void {
322
322
  const ids = getEffectiveIds(options);
323
323
  if (!ids) return;
324
- //TODO
324
+
325
+ const { withMethods, aka, akaMethods, protocols, from } = options;
325
326
  for (const key of idRefNormalKeys) {
326
327
  const parsed = parseIdRef(key);
327
328
  if (!parsed) continue;
@@ -332,15 +333,15 @@ function processIdRefNormalKeys(
332
333
  const value = expandedPattern[key];
333
334
  if (parsed.remainingPath) {
334
335
  const resolvedValue = getValues(
335
- { __v: value }, options.from,
336
- { withMethods: options.withMethods, aka: options.aka, akaMethods: options.akaMethods, protocols: options.protocols, root: target }
336
+ { __v: value }, from,
337
+ { withMethods, aka, akaMethods, protocols, root: target }
337
338
  );
338
339
  assignGingerly(el, { [parsed.remainingPath]: resolvedValue.__v }, options);
339
340
  } else {
340
341
  const resolvedValue = getValues(
341
342
  typeof value === 'object' && value !== null ? value : { __v: value },
342
- options.from,
343
- { withMethods: options.withMethods, aka: options.aka, akaMethods: options.akaMethods, protocols: options.protocols, root: target }
343
+ from,
344
+ { withMethods, aka, akaMethods, protocols, root: target }
344
345
  );
345
346
  if (!('__v' in resolvedValue)) {
346
347
  assignGingerly(el, resolvedValue, options);
@@ -46,7 +46,7 @@ export async function assignFromAsync(target, pattern, options, permissions) {
46
46
  if (idRefNormalKeys.length > 0 && (options.pin || options.at)) {
47
47
  const ids = { ...options.pin, ...options.at };
48
48
  const { resolveIdVariable, parseIdRef } = await import('./resolveIdRef.js');
49
- //TODO
49
+ const { withMethods, aka, akaMethods, protocols, from } = options;
50
50
  for (const key of idRefNormalKeys) {
51
51
  const parsed = parseIdRef(key);
52
52
  if (!parsed)
@@ -57,13 +57,13 @@ export async function assignFromAsync(target, pattern, options, permissions) {
57
57
  const value = expandedPattern[key];
58
58
  if (parsed.remainingPath) {
59
59
  // Resolve the RHS value
60
- const resolvedValue = await resolveValues({ __v: value }, options.from, { withMethods: options.withMethods, aka: options.aka, akaMethods: options.akaMethods, protocols: options.protocols, root: el });
60
+ const resolvedValue = await resolveValues({ __v: value }, from, { withMethods, aka, akaMethods, protocols, root: el });
61
61
  // Apply remaining path on the resolved element
62
62
  assignGingerly(el, { [parsed.remainingPath]: resolvedValue.__v }, options);
63
63
  }
64
64
  else {
65
65
  // No remaining path — resolve and assign directly to the element
66
- const resolvedValue = await resolveValues(typeof value === 'object' && value !== null ? value : { __v: value }, options.from, { withMethods: options.withMethods, aka: options.aka, akaMethods: options.akaMethods, protocols: options.protocols, root: el });
66
+ const resolvedValue = await resolveValues(typeof value === 'object' && value !== null ? value : { __v: value }, from, { withMethods, aka, akaMethods, protocols, root: el });
67
67
  if ('__v' in resolvedValue) {
68
68
  // Single value — can't assign to element root without a path
69
69
  }
@@ -83,7 +83,7 @@ export async function assignFromAsync(
83
83
  if (idRefNormalKeys.length > 0 && (options.pin || options.at)) {
84
84
  const ids = { ...options.pin, ...options.at };
85
85
  const { resolveIdVariable, parseIdRef } = await import('./resolveIdRef.js');
86
- //TODO
86
+ const { withMethods, aka, akaMethods, protocols, from } = options;
87
87
  for (const key of idRefNormalKeys) {
88
88
  const parsed = parseIdRef(key);
89
89
  if (!parsed) continue;
@@ -95,8 +95,8 @@ export async function assignFromAsync(
95
95
  if (parsed.remainingPath) {
96
96
  // Resolve the RHS value
97
97
  const resolvedValue = await resolveValues(
98
- { __v: value }, options.from,
99
- { withMethods: options.withMethods, aka: options.aka, akaMethods: options.akaMethods, protocols: options.protocols, root: el }
98
+ { __v: value }, from,
99
+ { withMethods, aka, akaMethods, protocols, root: el }
100
100
  );
101
101
  // Apply remaining path on the resolved element
102
102
  assignGingerly(el, { [parsed.remainingPath]: resolvedValue.__v }, options);
@@ -104,8 +104,8 @@ export async function assignFromAsync(
104
104
  // No remaining path — resolve and assign directly to the element
105
105
  const resolvedValue = await resolveValues(
106
106
  typeof value === 'object' && value !== null ? value : { __v: value },
107
- options.from,
108
- { withMethods: options.withMethods, aka: options.aka, akaMethods: options.akaMethods, protocols: options.protocols, root: el }
107
+ from,
108
+ { withMethods, aka, akaMethods, protocols, root: el }
109
109
  );
110
110
  if ('__v' in resolvedValue) {
111
111
  // Single value — can't assign to element root without a path
package/assignGingerly.js CHANGED
@@ -562,7 +562,6 @@ export function assignGingerly(target, source, options, permissions) {
562
562
  if (!target || typeof target !== 'object') {
563
563
  return target;
564
564
  }
565
- //TODO
566
565
  const { aliasMap, withMethods: withMethodsSet } = normalizeAliasOptions(options);
567
566
  // Convert withAsyncMethods array to Set for O(1) lookup
568
567
  const withAsyncMethodsSet = options?.withAsyncMethods
@@ -639,22 +638,61 @@ export function assignGingerly(target, source, options, permissions) {
639
638
  if (path) {
640
639
  if (isNestedPath(path)) {
641
640
  const pathParts = parsePath(path);
642
- const lastKey = pathParts[pathParts.length - 1];
643
- const parent = ensureNestedPath(target, pathParts);
644
- if (!(lastKey in parent)) {
645
- 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];
650
+ }
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;
646
666
  }
647
- else if (Array.isArray(parent[lastKey])) {
648
- parent[lastKey] = Array.isArray(value)
649
- ? [...parent[lastKey], ...value]
650
- : [...parent[lastKey], value];
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;
651
678
  }
652
679
  else {
653
- parent[lastKey] += value;
680
+ lhsParent[lhsKey] += value;
654
681
  }
655
682
  }
656
683
  else {
657
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
+ }
658
696
  if (!(path in target)) {
659
697
  target[path] = value;
660
698
  }
@@ -663,6 +701,10 @@ export function assignGingerly(target, source, options, permissions) {
663
701
  ? [...target[path], ...value]
664
702
  : [...target[path], value];
665
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
+ }
666
708
  else {
667
709
  target[path] += value;
668
710
  }
package/assignGingerly.ts CHANGED
@@ -767,7 +767,6 @@ export function assignGingerly(
767
767
  if (!target || typeof target !== 'object') {
768
768
  return target;
769
769
  }
770
- //TODO
771
770
 
772
771
  const { aliasMap, withMethods: withMethodsSet } = normalizeAliasOptions(options);
773
772
 
@@ -852,25 +851,69 @@ export function assignGingerly(
852
851
  if (path) {
853
852
  if (isNestedPath(path)) {
854
853
  const pathParts = parsePath(path);
855
- const lastKey = pathParts[pathParts.length - 1];
856
- const parent = ensureNestedPath(target, pathParts);
857
- if (!(lastKey in parent)) {
858
- parent[lastKey] = value;
859
- } else if (Array.isArray(parent[lastKey])) {
860
- parent[lastKey] = Array.isArray(value)
861
- ? [...parent[lastKey], ...value]
862
- : [...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];
864
+ } else {
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;
863
891
  } else {
864
- parent[lastKey] += value;
892
+ lhsParent[lhsKey] += value;
865
893
  }
866
894
  } else {
867
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
+
868
908
  if (!(path in target)) {
869
909
  target[path] = value;
870
910
  } else if (Array.isArray(target[path])) {
871
911
  target[path] = Array.isArray(value)
872
912
  ? [...target[path], ...value]
873
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;
874
917
  } else {
875
918
  target[path] += value;
876
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;
package/getValues.js CHANGED
@@ -16,7 +16,6 @@
16
16
  * count: 42
17
17
  * }, source, { withMethods: ['querySelector'], aka: { q: 'querySelector' } });
18
18
  */
19
- //TODO
20
19
  export function normalizeAliasOptions(options) {
21
20
  const aliasMap = new Map();
22
21
  if (options?.aka) {
package/getValues.ts CHANGED
@@ -18,7 +18,7 @@
18
18
  */
19
19
 
20
20
  import type { GetValuesOptions } from './types/assign-gingerly/types.js';
21
- //TODO
21
+
22
22
  export function normalizeAliasOptions(options?: {
23
23
  aka?: Record<string, string>;
24
24
  akaMethods?: Record<string, string>;