forwardRefs.mjs 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // Types
  2. const Refs = Symbol('Forwarded refs');
  3. /** Omit properties starting with P */
  4. /** Omit keyof $props from T */
  5. function getDescriptor(obj, key) {
  6. let currentObj = obj;
  7. while (currentObj) {
  8. const descriptor = Reflect.getOwnPropertyDescriptor(currentObj, key);
  9. if (descriptor) return descriptor;
  10. currentObj = Object.getPrototypeOf(currentObj);
  11. }
  12. return undefined;
  13. }
  14. export function forwardRefs(target) {
  15. for (var _len = arguments.length, refs = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  16. refs[_key - 1] = arguments[_key];
  17. }
  18. target[Refs] = refs;
  19. return new Proxy(target, {
  20. get(target, key) {
  21. if (Reflect.has(target, key)) {
  22. return Reflect.get(target, key);
  23. }
  24. // Skip internal properties
  25. if (typeof key === 'symbol' || key.startsWith('$') || key.startsWith('__')) return;
  26. for (const ref of refs) {
  27. if (ref.value && Reflect.has(ref.value, key)) {
  28. const val = Reflect.get(ref.value, key);
  29. return typeof val === 'function' ? val.bind(ref.value) : val;
  30. }
  31. }
  32. },
  33. has(target, key) {
  34. if (Reflect.has(target, key)) {
  35. return true;
  36. }
  37. // Skip internal properties
  38. if (typeof key === 'symbol' || key.startsWith('$') || key.startsWith('__')) return false;
  39. for (const ref of refs) {
  40. if (ref.value && Reflect.has(ref.value, key)) {
  41. return true;
  42. }
  43. }
  44. return false;
  45. },
  46. set(target, key, value) {
  47. if (Reflect.has(target, key)) {
  48. return Reflect.set(target, key, value);
  49. }
  50. // Skip internal properties
  51. if (typeof key === 'symbol' || key.startsWith('$') || key.startsWith('__')) return false;
  52. for (const ref of refs) {
  53. if (ref.value && Reflect.has(ref.value, key)) {
  54. return Reflect.set(ref.value, key, value);
  55. }
  56. }
  57. return false;
  58. },
  59. getOwnPropertyDescriptor(target, key) {
  60. const descriptor = Reflect.getOwnPropertyDescriptor(target, key);
  61. if (descriptor) return descriptor;
  62. // Skip internal properties
  63. if (typeof key === 'symbol' || key.startsWith('$') || key.startsWith('__')) return;
  64. // Check each ref's own properties
  65. for (const ref of refs) {
  66. if (!ref.value) continue;
  67. const descriptor = getDescriptor(ref.value, key) ?? ('_' in ref.value ? getDescriptor(ref.value._?.setupState, key) : undefined);
  68. if (descriptor) return descriptor;
  69. }
  70. // Recursive search up each ref's prototype
  71. for (const ref of refs) {
  72. const childRefs = ref.value && ref.value[Refs];
  73. if (!childRefs) continue;
  74. const queue = childRefs.slice();
  75. while (queue.length) {
  76. const ref = queue.shift();
  77. const descriptor = getDescriptor(ref.value, key);
  78. if (descriptor) return descriptor;
  79. const childRefs = ref.value && ref.value[Refs];
  80. if (childRefs) queue.push(...childRefs);
  81. }
  82. }
  83. return undefined;
  84. }
  85. });
  86. }
  87. //# sourceMappingURL=forwardRefs.mjs.map