module-proxy.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.createProxy = createProxy;
  6. /**
  7. * Copyright (c) Facebook, Inc. and its affiliates.
  8. *
  9. * This source code is licensed under the MIT license found in the
  10. * LICENSE file in the root directory of this source tree.
  11. */ // Modified from https://github.com/facebook/react/blob/main/packages/react-server-dom-webpack/src/ReactFlightWebpackNodeRegister.js
  12. const MODULE_REFERENCE = Symbol.for("react.module.reference");
  13. const PROMISE_PROTOTYPE = Promise.prototype;
  14. const proxyHandlers = {
  15. get: function(target, name, _receiver) {
  16. switch(name){
  17. // These names are read by the Flight runtime if you end up using the exports object.
  18. case "$$typeof":
  19. // These names are a little too common. We should probably have a way to
  20. // have the Flight runtime extract the inner target instead.
  21. return target.$$typeof;
  22. case "filepath":
  23. return target.filepath;
  24. case "name":
  25. return target.name;
  26. case "async":
  27. return target.async;
  28. // We need to special case this because createElement reads it if we pass this
  29. // reference.
  30. case "defaultProps":
  31. return undefined;
  32. case "__esModule":
  33. // Something is conditionally checking which export to use. We'll pretend to be
  34. // an ESM compat module but then we'll check again on the client.
  35. target.default = {
  36. $$typeof: MODULE_REFERENCE,
  37. filepath: target.filepath,
  38. // This a placeholder value that tells the client to conditionally use the
  39. // whole object or just the default export.
  40. name: "",
  41. async: target.async
  42. };
  43. return true;
  44. case "then":
  45. if (!target.async) {
  46. // If this module is expected to return a Promise (such as an AsyncModule) then
  47. // we should resolve that with a client reference that unwraps the Promise on
  48. // the client.
  49. const then = function then(resolve, _reject) {
  50. const moduleReference = {
  51. $$typeof: MODULE_REFERENCE,
  52. filepath: target.filepath,
  53. name: "*",
  54. async: true
  55. };
  56. return Promise.resolve(resolve(new Proxy(moduleReference, proxyHandlers)));
  57. };
  58. // If this is not used as a Promise but is treated as a reference to a `.then`
  59. // export then we should treat it as a reference to that name.
  60. then.$$typeof = MODULE_REFERENCE;
  61. then.filepath = target.filepath;
  62. // then.name is conveniently already "then" which is the export name we need.
  63. // This will break if it's minified though.
  64. return then;
  65. }
  66. break;
  67. default:
  68. break;
  69. }
  70. let cachedReference = target[name];
  71. if (!cachedReference) {
  72. cachedReference = target[name] = {
  73. $$typeof: MODULE_REFERENCE,
  74. filepath: target.filepath,
  75. name: name,
  76. async: target.async
  77. };
  78. }
  79. return cachedReference;
  80. },
  81. getPrototypeOf (_target) {
  82. // Pretend to be a Promise in case anyone asks.
  83. return PROMISE_PROTOTYPE;
  84. },
  85. set: function() {
  86. throw new Error("Cannot assign to a client module from a server module.");
  87. }
  88. };
  89. function createProxy(moduleId) {
  90. const moduleReference = {
  91. $$typeof: MODULE_REFERENCE,
  92. filepath: moduleId,
  93. name: "*",
  94. async: false
  95. };
  96. return new Proxy(moduleReference, proxyHandlers);
  97. }
  98. //# sourceMappingURL=module-proxy.js.map