aberdeen 1.0.8 → 1.0.11

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/src/aberdeen.ts CHANGED
@@ -114,9 +114,9 @@ function partToStr(part: number | string): string {
114
114
  * 1 - separator between string array items
115
115
  * 65535 - for compatibility
116
116
  */
117
- result += String.fromCharCode(
117
+ result = String.fromCharCode(
118
118
  negative ? 65534 - (num % 65533) : 2 + (num % 65533),
119
- );
119
+ ) + result;
120
120
  num = Math.floor(num / 65533);
121
121
  }
122
122
  // Prefix the number of digits, counting down from 128 for negative and up for positive
@@ -822,15 +822,19 @@ function subscribe(
822
822
  }
823
823
  }
824
824
 
825
+ // Records in TypeScript pretend that they can have number keys, but in reality they are converted to string.
826
+ // This type changes (number | something) types to (string | something) types, maintaining typing precision as much as possible.
827
+ type KeyToString<K> = K extends number ? string : K extends string | symbol ? K : K extends number | infer U ? string | U : K;
828
+
825
829
  export function onEach<T>(
826
- target: Array<undefined | T>,
830
+ target: ReadonlyArray<undefined | T>,
827
831
  render: (value: T, index: number) => void,
828
- makeKey?: (value: T, key: any) => SortKeyType,
832
+ makeKey?: (value: T, index: number) => SortKeyType,
829
833
  ): void;
830
834
  export function onEach<K extends string | number | symbol, T>(
831
835
  target: Record<K, undefined | T>,
832
- render: (value: T, index: K) => void,
833
- makeKey?: (value: T, key: K) => SortKeyType,
836
+ render: (value: T, index: KeyToString<K>) => void,
837
+ makeKey?: (value: T, index: KeyToString<K>) => SortKeyType,
834
838
  ): void;
835
839
 
836
840
  /**
@@ -1584,9 +1588,9 @@ const SPECIAL_PROPS: { [key: string]: (value: any) => void } = {
1584
1588
  addNode(document.createTextNode(value));
1585
1589
  },
1586
1590
  element: (value: any) => {
1587
- if (!(value instanceof Node))
1588
- throw new Error(`Unexpected element-argument: ${JSON.parse(value)}`);
1591
+ console.log("Aberdeen: $({element: myElement}) is deprecated, use $(myElement) instead");
1589
1592
  addNode(value);
1593
+ SPECIAL_PROPS.element = addNode; // Avoid the console.log next time
1590
1594
  },
1591
1595
  };
1592
1596
 
@@ -1623,7 +1627,7 @@ const SPECIAL_PROPS: { [key: string]: (value: any) => void } = {
1623
1627
  * This is often used together with {@link ref}, in order to use properties other than `.value`.
1624
1628
  * - `{text: string|number}`: Add the value as a `TextNode` to the *current* element.
1625
1629
  * - `{html: string}`: Add the value as HTML to the *current* element. This should only be used in exceptional situations. And of course, beware of XSS.
1626
- * - `{element: Node}`: Add a pre-existing HTML `Node` to the *current* element.
1630
+ - `Node`: If a DOM Node (Element or TextNode) is passed in, it is added as a child to the *current* element. If the Node is an Element, it becomes the new *current* element for the rest of this `$` function execution.
1627
1631
  *
1628
1632
  * @returns The most inner DOM element that was created (not counting text nodes nor elements created by content functions),
1629
1633
  * or undefined if no elements were created.
@@ -1746,12 +1750,23 @@ export function $(
1746
1750
  }
1747
1751
  } else if (typeof arg === "object") {
1748
1752
  if (arg.constructor !== Object) {
1749
- err = `Unexpected argument: ${arg}`;
1750
- break;
1751
- }
1752
- for (const key in arg) {
1753
- const val = arg[key];
1754
- applyArg(key, val);
1753
+ if (arg instanceof Node) {
1754
+ addNode(arg);
1755
+ if (arg instanceof Element) {
1756
+ // If it's an Element, it may contain children, so we make it the current scope
1757
+ if (!savedCurrentScope) savedCurrentScope = currentScope;
1758
+ currentScope = new ChainedScope(arg, true);
1759
+ currentScope.lastChild = arg.lastChild || undefined;
1760
+ }
1761
+ } else {
1762
+ err = `Unexpected argument: ${arg}`;
1763
+ break;
1764
+ }
1765
+ } else {
1766
+ for (const key in arg) {
1767
+ const val = arg[key];
1768
+ applyArg(key, val);
1769
+ }
1755
1770
  }
1756
1771
  } else if (typeof arg === "function") {
1757
1772
  new RegularScope(currentScope.parentElement, arg);
@@ -2210,9 +2225,9 @@ export function peek<T>(func: () => T): T {
2210
2225
  }
2211
2226
 
2212
2227
  /** When using an object as `source`. */
2213
- export function map<IN, OUT>(
2214
- source: Record<string | symbol, IN>,
2215
- func: (value: IN, index: string | symbol) => undefined | OUT,
2228
+ export function map<IN, const IN_KEY extends string | number | symbol, OUT>(
2229
+ source: Record<IN_KEY, IN>,
2230
+ func: (value: IN, index: KeyToString<IN_KEY>) => undefined | OUT,
2216
2231
  ): Record<string | symbol, OUT>;
2217
2232
  /** When using an array as `source`. */
2218
2233
  export function map<IN, OUT>(
@@ -2289,7 +2304,7 @@ export function multiMap<
2289
2304
  K extends string | number | symbol,
2290
2305
  IN,
2291
2306
  OUT extends { [key: string | symbol]: DatumType },
2292
- >(source: Record<K, IN>, func: (value: IN, index: K) => OUT | undefined): OUT;
2307
+ >(source: Record<K, IN>, func: (value: IN, index: KeyToString<K>) => OUT | undefined): OUT;
2293
2308
  /**
2294
2309
  * Reactively maps items from a source proxy (array or object) to a target proxied object,
2295
2310
  * where each source item can contribute multiple key-value pairs to the target.
@@ -2436,18 +2451,18 @@ export function partition<
2436
2451
  IN_V,
2437
2452
  >(
2438
2453
  source: Record<IN_K, IN_V>,
2439
- func: (value: IN_V, key: IN_K) => undefined | OUT_K | OUT_K[],
2440
- ): Record<OUT_K, Record<IN_K, IN_V>> {
2441
- const unproxiedOut = {} as Record<OUT_K, Record<IN_K, IN_V>>;
2454
+ func: (value: IN_V, key: KeyToString<IN_K>) => undefined | OUT_K | OUT_K[],
2455
+ ): Record<OUT_K, Record<KeyToString<IN_K>, IN_V>> {
2456
+ const unproxiedOut = {} as Record<OUT_K, Record<KeyToString<IN_K>, IN_V>>;
2442
2457
  const out = proxy(unproxiedOut);
2443
- onEach(source, (item: IN_V, key: IN_K) => {
2458
+ onEach(source, (item: IN_V, key: KeyToString<IN_K>) => {
2444
2459
  const rsp = func(item, key);
2445
2460
  if (rsp != null) {
2446
2461
  const buckets = rsp instanceof Array ? rsp : [rsp];
2447
2462
  if (buckets.length) {
2448
2463
  for (const bucket of buckets) {
2449
2464
  if (unproxiedOut[bucket]) out[bucket][key] = item;
2450
- else out[bucket] = { [key]: item } as Record<IN_K, IN_V>;
2465
+ else out[bucket] = { [key]: item } as Record<KeyToString<IN_K>, IN_V>;
2451
2466
  }
2452
2467
  clean(() => {
2453
2468
  for (const bucket of buckets) {