@bleedingdev/modern-js-plugin-bff 3.5.0-ultramodern.0 → 3.5.0-ultramodern.2

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.
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, getters, values)=>{
5
+ var define = (defs, kind)=>{
6
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
7
+ enumerable: true,
8
+ [kind]: defs[key]
9
+ });
10
+ };
11
+ define(getters, "get");
12
+ define(values, "value");
13
+ };
14
+ })();
15
+ (()=>{
16
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
17
+ })();
18
+ (()=>{
19
+ __webpack_require__.r = (exports1)=>{
20
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
21
+ value: 'Module'
22
+ });
23
+ Object.defineProperty(exports1, '__esModule', {
24
+ value: true
25
+ });
26
+ };
27
+ })();
28
+ var __webpack_exports__ = {};
29
+ __webpack_require__.r(__webpack_exports__);
30
+ __webpack_require__.d(__webpack_exports__, {
31
+ createEffectOperationContext: ()=>external_operation_context_js_namespaceObject.createEffectOperationContext,
32
+ runWithEffectContext: ()=>runWithEffectContext,
33
+ useEffectContext: ()=>useEffectContext,
34
+ useOperationContext: ()=>useOperationContext
35
+ });
36
+ const external_operation_context_js_namespaceObject = require("./operation-context.js");
37
+ const kEffectContext = Symbol.for('modernjs.plugin-bff.edgeEffectContext');
38
+ const kEffectContextStorage = Symbol.for('modernjs.plugin-bff.edgeEffectContextStorage');
39
+ const globalStore = globalThis;
40
+ const isPromiseLike = (value)=>'object' == typeof value && null !== value && 'then' in value && 'function' == typeof value.then;
41
+ const getRuntimeStorage = ()=>{
42
+ if (globalStore[kEffectContextStorage]) return globalStore[kEffectContextStorage];
43
+ if ('function' == typeof globalStore.AsyncLocalStorage) globalStore[kEffectContextStorage] = new globalStore.AsyncLocalStorage();
44
+ return globalStore[kEffectContextStorage];
45
+ };
46
+ const runWithEffectContext = (context, cb)=>{
47
+ const storage = getRuntimeStorage();
48
+ if (storage) return storage.run(context, cb);
49
+ const previous = globalStore[kEffectContext];
50
+ globalStore[kEffectContext] = context;
51
+ try {
52
+ const result = cb();
53
+ if (isPromiseLike(result)) return Promise.resolve(result).finally(()=>{
54
+ globalStore[kEffectContext] = previous;
55
+ });
56
+ globalStore[kEffectContext] = previous;
57
+ return result;
58
+ } catch (error) {
59
+ globalStore[kEffectContext] = previous;
60
+ throw error;
61
+ }
62
+ };
63
+ const useEffectContext = ()=>{
64
+ const context = getRuntimeStorage()?.getStore() ?? globalStore[kEffectContext];
65
+ if (!context) throw new Error("Can't call useEffectContext out of Effect runtime scope");
66
+ return context;
67
+ };
68
+ const useOperationContext = ()=>useEffectContext().operationContext;
69
+ exports.createEffectOperationContext = __webpack_exports__.createEffectOperationContext;
70
+ exports.runWithEffectContext = __webpack_exports__.runWithEffectContext;
71
+ exports.useEffectContext = __webpack_exports__.useEffectContext;
72
+ exports.useOperationContext = __webpack_exports__.useOperationContext;
73
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
74
+ "createEffectOperationContext",
75
+ "runWithEffectContext",
76
+ "useEffectContext",
77
+ "useOperationContext"
78
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
79
+ Object.defineProperty(exports, '__esModule', {
80
+ value: true
81
+ });
@@ -3,6 +3,9 @@ var __webpack_modules__ = {
3
3
  "../safe-failure" (module) {
4
4
  module.exports = require("../safe-failure.js");
5
5
  },
6
+ "./edge-context" (module) {
7
+ module.exports = require("./edge-context.js");
8
+ },
6
9
  "./handler" (module) {
7
10
  module.exports = require("./handler.js");
8
11
  },
@@ -61,16 +64,21 @@ var __webpack_exports__ = {};
61
64
  (()=>{
62
65
  __webpack_require__.r(__webpack_exports__);
63
66
  var _safe_failure__rspack_import_0 = __webpack_require__("../safe-failure");
64
- var _module__rspack_import_1 = __webpack_require__("./module");
65
- var _operation_context__rspack_import_2 = __webpack_require__("./operation-context");
66
- var _handler__rspack_import_3 = __webpack_require__("./handler");
67
+ var _edge_context__rspack_import_1 = __webpack_require__("./edge-context");
68
+ var _module__rspack_import_2 = __webpack_require__("./module");
69
+ var _operation_context__rspack_import_3 = __webpack_require__("./operation-context");
70
+ var _handler__rspack_import_4 = __webpack_require__("./handler");
67
71
  var __rspack_reexport = {};
68
- for(const __rspack_import_key in _handler__rspack_import_3)if ([
72
+ for(const __rspack_import_key in _handler__rspack_import_4)if ([
73
+ "runWithEffectContext",
74
+ "useEffectContext",
69
75
  "default",
70
- "dispatchEffectBffRequest",
76
+ "useOperationContext",
71
77
  "createEffectOperationContext",
78
+ "dispatchEffectBffRequest",
79
+ "createEffectBffTestHandler",
72
80
  "createEffectBffEdgeHandler"
73
- ].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>_handler__rspack_import_3[__rspack_import_key];
81
+ ].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>_handler__rspack_import_4[__rspack_import_key];
74
82
  __webpack_require__.d(__webpack_exports__, __rspack_reexport);
75
83
  function normalizePrefix(prefix) {
76
84
  if (!prefix || '/' === prefix) return '';
@@ -101,7 +109,7 @@ var __webpack_exports__ = {};
101
109
  env: options.env || {},
102
110
  path: originalPath,
103
111
  method,
104
- operationContext: (0, _operation_context__rspack_import_2.createEffectOperationContext)({
112
+ operationContext: (0, _operation_context__rspack_import_3.createEffectOperationContext)({
105
113
  request: effectRequest,
106
114
  env: options.env || {},
107
115
  path: originalPath,
@@ -120,7 +128,7 @@ var __webpack_exports__ = {};
120
128
  const effectRequest = createRequestForMountedPrefix(request, options.prefix);
121
129
  const effectContext = createEdgeEffectContext(request, effectRequest, options);
122
130
  try {
123
- const response = handler.length > 1 ? await handler(effectRequest, effectContext) : await handler(effectRequest);
131
+ const response = await (0, _edge_context__rspack_import_1.runWithEffectContext)(effectContext, ()=>handler.length > 1 ? handler(effectRequest, effectContext) : handler(effectRequest));
124
132
  if (!(response instanceof Response)) throw new Error('[BFF][Effect] Effect handler must return a Response instance.');
125
133
  return new Response(response.body, response);
126
134
  } catch (error) {
@@ -132,8 +140,9 @@ var __webpack_exports__ = {};
132
140
  return createRuntimeErrorResponse(error);
133
141
  }
134
142
  }
143
+ const createEffectBffTestHandler = createEffectBffEdgeHandler;
135
144
  async function createEffectBffEdgeHandler(options) {
136
- const loaded = await (0, _module__rspack_import_1.resolveEffectBffModuleHandler)(options.module, {
145
+ const loaded = await (0, _module__rspack_import_2.resolveEffectBffModuleHandler)(options.module, {
137
146
  openapi: options.openapi,
138
147
  dataPlatform: options.dataPlatform,
139
148
  onWarning: options.onWarning
@@ -152,17 +161,30 @@ var __webpack_exports__ = {};
152
161
  }
153
162
  __webpack_require__.d(__webpack_exports__, {
154
163
  createEffectBffEdgeHandler: ()=>createEffectBffEdgeHandler,
155
- createEffectOperationContext: ()=>_operation_context__rspack_import_2.createEffectOperationContext,
156
- dispatchEffectBffRequest: ()=>dispatchEffectBffRequest
164
+ createEffectOperationContext: ()=>_operation_context__rspack_import_3.createEffectOperationContext,
165
+ dispatchEffectBffRequest: ()=>dispatchEffectBffRequest,
166
+ runWithEffectContext: ()=>_edge_context__rspack_import_1.runWithEffectContext,
167
+ useEffectContext: ()=>_edge_context__rspack_import_1.useEffectContext,
168
+ useOperationContext: ()=>_edge_context__rspack_import_1.useOperationContext
169
+ }, {
170
+ createEffectBffTestHandler: createEffectBffTestHandler
157
171
  });
158
172
  })();
159
173
  exports.createEffectBffEdgeHandler = __webpack_exports__.createEffectBffEdgeHandler;
174
+ exports.createEffectBffTestHandler = __webpack_exports__.createEffectBffTestHandler;
160
175
  exports.createEffectOperationContext = __webpack_exports__.createEffectOperationContext;
161
176
  exports.dispatchEffectBffRequest = __webpack_exports__.dispatchEffectBffRequest;
177
+ exports.runWithEffectContext = __webpack_exports__.runWithEffectContext;
178
+ exports.useEffectContext = __webpack_exports__.useEffectContext;
179
+ exports.useOperationContext = __webpack_exports__.useOperationContext;
162
180
  for(var __rspack_i in __webpack_exports__)if (-1 === [
163
181
  "createEffectBffEdgeHandler",
182
+ "createEffectBffTestHandler",
164
183
  "createEffectOperationContext",
165
- "dispatchEffectBffRequest"
184
+ "dispatchEffectBffRequest",
185
+ "runWithEffectContext",
186
+ "useEffectContext",
187
+ "useOperationContext"
166
188
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
167
189
  Object.defineProperty(exports, '__esModule', {
168
190
  value: true
@@ -140,6 +140,8 @@ var __webpack_exports__ = {};
140
140
  ].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>effect_unstable_rpc__rspack_import_4[__rspack_import_key];
141
141
  __webpack_require__.d(__webpack_exports__, __rspack_reexport);
142
142
  const emptyEffectServiceContext = effect_Context__rspack_import_0.empty();
143
+ const isEffectServiceContext = (context)=>'object' == typeof context && null !== context && 'mapUnsafe' in context;
144
+ const toEffectServiceContext = (context)=>isEffectServiceContext(context) ? context : emptyEffectServiceContext;
143
145
  const EFFECT_VALIDATOR_AWARE_FACTORY = Symbol.for('modernjs.effect.validatorAware');
144
146
  function isValidatorAwareHandlerFactory(factory) {
145
147
  return 'function' == typeof factory && true === factory[EFFECT_VALIDATOR_AWARE_FACTORY];
@@ -498,7 +500,7 @@ var __webpack_exports__ = {};
498
500
  if (preparedRequest instanceof Response) return preparedRequest;
499
501
  const validationError = validateDataPlatformRequestEnvelope(preparedRequest, options.dataPlatform);
500
502
  if (validationError) return validationError;
501
- return httpApiHandler.handler(preparedRequest, context ?? emptyEffectServiceContext);
503
+ return httpApiHandler.handler(preparedRequest, toEffectServiceContext(context));
502
504
  };
503
505
  const handleBatchRequest = async (request, context)=>{
504
506
  const mountedPrefix = getMountedPrefixFromContext(request, context);
@@ -620,7 +622,7 @@ var __webpack_exports__ = {};
620
622
  if (isRpcRequest(request, rpcPath)) {
621
623
  const policyDenial = options.validateRequest?.(request);
622
624
  if (policyDenial) return policyDenial;
623
- return rpcHandler.handler(request, context ?? emptyEffectServiceContext);
625
+ return rpcHandler.handler(request, toEffectServiceContext(context));
624
626
  }
625
627
  return handleHttpApiRequest(request);
626
628
  },
@@ -3,6 +3,9 @@ var __webpack_modules__ = {
3
3
  "./context" (module) {
4
4
  module.exports = require("./context.js");
5
5
  },
6
+ "./edge" (module) {
7
+ module.exports = require("./edge.js");
8
+ },
6
9
  "./handler" (module) {
7
10
  module.exports = require("./handler.js");
8
11
  },
@@ -59,30 +62,47 @@ var __webpack_exports__ = {};
59
62
  __webpack_require__.r(__webpack_exports__);
60
63
  var _effect_opentelemetry__rspack_import_0 = __webpack_require__("@effect/opentelemetry");
61
64
  var _context__rspack_import_1 = __webpack_require__("./context");
62
- var _handler__rspack_import_2 = __webpack_require__("./handler");
65
+ var _edge__rspack_import_2 = __webpack_require__("./edge");
66
+ var _handler__rspack_import_3 = __webpack_require__("./handler");
63
67
  var __rspack_reexport = {};
64
- for(const __rspack_import_key in _handler__rspack_import_2)if ([
68
+ for(const __rspack_import_key in _handler__rspack_import_3)if ([
69
+ "runWithEffectContext",
65
70
  "useEffectContext",
66
71
  "default",
67
- "OpenTelemetry",
72
+ "useOperationContext",
68
73
  "createEffectOperationContext",
69
- "useOperationContext"
70
- ].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>_handler__rspack_import_2[__rspack_import_key];
74
+ "dispatchEffectBffRequest",
75
+ "createEffectBffTestHandler",
76
+ "OpenTelemetry",
77
+ "createEffectBffEdgeHandler"
78
+ ].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>_handler__rspack_import_3[__rspack_import_key];
71
79
  __webpack_require__.d(__webpack_exports__, __rspack_reexport);
72
80
  __webpack_require__.d(__webpack_exports__, {
73
81
  OpenTelemetry: ()=>_effect_opentelemetry__rspack_import_0,
82
+ createEffectBffEdgeHandler: ()=>_edge__rspack_import_2.createEffectBffEdgeHandler,
83
+ createEffectBffTestHandler: ()=>_edge__rspack_import_2.createEffectBffTestHandler,
74
84
  createEffectOperationContext: ()=>_context__rspack_import_1.createEffectOperationContext,
85
+ dispatchEffectBffRequest: ()=>_edge__rspack_import_2.dispatchEffectBffRequest,
86
+ runWithEffectContext: ()=>_context__rspack_import_1.runWithEffectContext,
75
87
  useEffectContext: ()=>_context__rspack_import_1.useEffectContext,
76
88
  useOperationContext: ()=>_context__rspack_import_1.useOperationContext
77
89
  });
78
90
  })();
79
91
  exports.OpenTelemetry = __webpack_exports__.OpenTelemetry;
92
+ exports.createEffectBffEdgeHandler = __webpack_exports__.createEffectBffEdgeHandler;
93
+ exports.createEffectBffTestHandler = __webpack_exports__.createEffectBffTestHandler;
80
94
  exports.createEffectOperationContext = __webpack_exports__.createEffectOperationContext;
95
+ exports.dispatchEffectBffRequest = __webpack_exports__.dispatchEffectBffRequest;
96
+ exports.runWithEffectContext = __webpack_exports__.runWithEffectContext;
81
97
  exports.useEffectContext = __webpack_exports__.useEffectContext;
82
98
  exports.useOperationContext = __webpack_exports__.useOperationContext;
83
99
  for(var __rspack_i in __webpack_exports__)if (-1 === [
84
100
  "OpenTelemetry",
101
+ "createEffectBffEdgeHandler",
102
+ "createEffectBffTestHandler",
85
103
  "createEffectOperationContext",
104
+ "dispatchEffectBffRequest",
105
+ "runWithEffectContext",
86
106
  "useEffectContext",
87
107
  "useOperationContext"
88
108
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
@@ -0,0 +1,34 @@
1
+ const kEffectContext = Symbol.for('modernjs.plugin-bff.edgeEffectContext');
2
+ const kEffectContextStorage = Symbol.for('modernjs.plugin-bff.edgeEffectContextStorage');
3
+ const globalStore = globalThis;
4
+ const isPromiseLike = (value)=>'object' == typeof value && null !== value && 'then' in value && 'function' == typeof value.then;
5
+ const getRuntimeStorage = ()=>{
6
+ if (globalStore[kEffectContextStorage]) return globalStore[kEffectContextStorage];
7
+ if ('function' == typeof globalStore.AsyncLocalStorage) globalStore[kEffectContextStorage] = new globalStore.AsyncLocalStorage();
8
+ return globalStore[kEffectContextStorage];
9
+ };
10
+ const runWithEffectContext = (context, cb)=>{
11
+ const storage = getRuntimeStorage();
12
+ if (storage) return storage.run(context, cb);
13
+ const previous = globalStore[kEffectContext];
14
+ globalStore[kEffectContext] = context;
15
+ try {
16
+ const result = cb();
17
+ if (isPromiseLike(result)) return Promise.resolve(result).finally(()=>{
18
+ globalStore[kEffectContext] = previous;
19
+ });
20
+ globalStore[kEffectContext] = previous;
21
+ return result;
22
+ } catch (error) {
23
+ globalStore[kEffectContext] = previous;
24
+ throw error;
25
+ }
26
+ };
27
+ const useEffectContext = ()=>{
28
+ const context = getRuntimeStorage()?.getStore() ?? globalStore[kEffectContext];
29
+ if (!context) throw new Error("Can't call useEffectContext out of Effect runtime scope");
30
+ return context;
31
+ };
32
+ const useOperationContext = ()=>useEffectContext().operationContext;
33
+ export { createEffectOperationContext } from "./operation-context.mjs";
34
+ export { runWithEffectContext, useEffectContext, useOperationContext };
@@ -1,4 +1,5 @@
1
1
  import { createSafeFailureResponse } from "../safe-failure.mjs";
2
+ import { runWithEffectContext, useEffectContext, useOperationContext } from "./edge-context.mjs";
2
3
  import { resolveEffectBffModuleHandler } from "./module.mjs";
3
4
  import { createEffectOperationContext } from "./operation-context.mjs";
4
5
  export * from "./handler.mjs";
@@ -50,7 +51,7 @@ async function dispatchEffectBffRequest(handler, request, options = {}) {
50
51
  const effectRequest = createRequestForMountedPrefix(request, options.prefix);
51
52
  const effectContext = createEdgeEffectContext(request, effectRequest, options);
52
53
  try {
53
- const response = handler.length > 1 ? await handler(effectRequest, effectContext) : await handler(effectRequest);
54
+ const response = await runWithEffectContext(effectContext, ()=>handler.length > 1 ? handler(effectRequest, effectContext) : handler(effectRequest));
54
55
  if (!(response instanceof Response)) throw new Error('[BFF][Effect] Effect handler must return a Response instance.');
55
56
  return new Response(response.body, response);
56
57
  } catch (error) {
@@ -62,6 +63,7 @@ async function dispatchEffectBffRequest(handler, request, options = {}) {
62
63
  return createRuntimeErrorResponse(error);
63
64
  }
64
65
  }
66
+ const createEffectBffTestHandler = createEffectBffEdgeHandler;
65
67
  async function createEffectBffEdgeHandler(options) {
66
68
  const loaded = await resolveEffectBffModuleHandler(options.module, {
67
69
  openapi: options.openapi,
@@ -80,4 +82,4 @@ async function createEffectBffEdgeHandler(options) {
80
82
  }
81
83
  };
82
84
  }
83
- export { createEffectBffEdgeHandler, createEffectOperationContext, dispatchEffectBffRequest };
85
+ export { createEffectBffEdgeHandler, createEffectBffTestHandler, createEffectOperationContext, dispatchEffectBffRequest, runWithEffectContext, useEffectContext, useOperationContext };
@@ -12,6 +12,8 @@ export * from "effect/unstable/httpapi";
12
12
  export * from "effect/unstable/rpc";
13
13
  import * as __rspack_external_effect_Context_f1289ca3 from "effect/Context";
14
14
  const emptyEffectServiceContext = __rspack_external_effect_Context_f1289ca3.empty();
15
+ const isEffectServiceContext = (context)=>'object' == typeof context && null !== context && 'mapUnsafe' in context;
16
+ const toEffectServiceContext = (context)=>isEffectServiceContext(context) ? context : emptyEffectServiceContext;
15
17
  const EFFECT_VALIDATOR_AWARE_FACTORY = Symbol.for('modernjs.effect.validatorAware');
16
18
  function isValidatorAwareHandlerFactory(factory) {
17
19
  return 'function' == typeof factory && true === factory[EFFECT_VALIDATOR_AWARE_FACTORY];
@@ -370,7 +372,7 @@ function createHttpApiHandler(options) {
370
372
  if (preparedRequest instanceof Response) return preparedRequest;
371
373
  const validationError = validateDataPlatformRequestEnvelope(preparedRequest, options.dataPlatform);
372
374
  if (validationError) return validationError;
373
- return httpApiHandler.handler(preparedRequest, context ?? emptyEffectServiceContext);
375
+ return httpApiHandler.handler(preparedRequest, toEffectServiceContext(context));
374
376
  };
375
377
  const handleBatchRequest = async (request, context)=>{
376
378
  const mountedPrefix = getMountedPrefixFromContext(request, context);
@@ -492,7 +494,7 @@ function createHttpApiHandler(options) {
492
494
  if (isRpcRequest(request, rpcPath)) {
493
495
  const policyDenial = options.validateRequest?.(request);
494
496
  if (policyDenial) return policyDenial;
495
- return rpcHandler.handler(request, context ?? emptyEffectServiceContext);
497
+ return rpcHandler.handler(request, toEffectServiceContext(context));
496
498
  }
497
499
  return handleHttpApiRequest(request);
498
500
  },
@@ -1,4 +1,5 @@
1
1
  import * as __rspack_external__effect_opentelemetry_8bbbb5af from "@effect/opentelemetry";
2
2
  export * from "./handler.mjs";
3
- export { createEffectOperationContext, useEffectContext, useOperationContext } from "./context.mjs";
3
+ export { createEffectOperationContext, runWithEffectContext, useEffectContext, useOperationContext } from "./context.mjs";
4
+ export { createEffectBffEdgeHandler, createEffectBffTestHandler, dispatchEffectBffRequest } from "./edge.mjs";
4
5
  export { __rspack_external__effect_opentelemetry_8bbbb5af as OpenTelemetry };
@@ -8,7 +8,7 @@ import pluginGenerator from "./utils/pluginGenerator.mjs";
8
8
  import runtimeGenerator from "./utils/runtimeGenerator.mjs";
9
9
  import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
10
10
  import { dirname as __rspack_dirname } from "node:path";
11
- var cli_dirname = __rspack_dirname(__rspack_fileURLToPath(import.meta.url));
11
+ var __rspack_import_meta_dirname__ = __rspack_dirname(__rspack_fileURLToPath(import.meta.url));
12
12
  const RUNTIME_CREATE_REQUEST = '@modern-js/plugin-bff/client';
13
13
  const WATCHABLE_EXTENSIONS = [
14
14
  '.ts',
@@ -165,7 +165,7 @@ const bffPlugin = ()=>({
165
165
  const apiRegexp = new RegExp(normalizeOutputPath(`${apiDirectory}${path.sep}.*(.[tj]s)$`));
166
166
  const name = isServer ? 'server' : 'client';
167
167
  const sourceExt = 'mjs';
168
- const loaderPath = path.join(cli_dirname, `loader.${sourceExt}`);
168
+ const loaderPath = path.join(__rspack_import_meta_dirname__, `loader.${sourceExt}`);
169
169
  chain.module.rule(CHAIN_ID.RULE.JS).exclude.add(apiRegexp);
170
170
  chain.module.rule('js-bff-api').test(apiRegexp).use('custom-loader').loader(loaderPath.replace(/\\/g, '/')).options({
171
171
  prefix,
@@ -0,0 +1,35 @@
1
+ import "node:module";
2
+ const kEffectContext = Symbol.for('modernjs.plugin-bff.edgeEffectContext');
3
+ const kEffectContextStorage = Symbol.for('modernjs.plugin-bff.edgeEffectContextStorage');
4
+ const globalStore = globalThis;
5
+ const isPromiseLike = (value)=>'object' == typeof value && null !== value && 'then' in value && 'function' == typeof value.then;
6
+ const getRuntimeStorage = ()=>{
7
+ if (globalStore[kEffectContextStorage]) return globalStore[kEffectContextStorage];
8
+ if ('function' == typeof globalStore.AsyncLocalStorage) globalStore[kEffectContextStorage] = new globalStore.AsyncLocalStorage();
9
+ return globalStore[kEffectContextStorage];
10
+ };
11
+ const runWithEffectContext = (context, cb)=>{
12
+ const storage = getRuntimeStorage();
13
+ if (storage) return storage.run(context, cb);
14
+ const previous = globalStore[kEffectContext];
15
+ globalStore[kEffectContext] = context;
16
+ try {
17
+ const result = cb();
18
+ if (isPromiseLike(result)) return Promise.resolve(result).finally(()=>{
19
+ globalStore[kEffectContext] = previous;
20
+ });
21
+ globalStore[kEffectContext] = previous;
22
+ return result;
23
+ } catch (error) {
24
+ globalStore[kEffectContext] = previous;
25
+ throw error;
26
+ }
27
+ };
28
+ const useEffectContext = ()=>{
29
+ const context = getRuntimeStorage()?.getStore() ?? globalStore[kEffectContext];
30
+ if (!context) throw new Error("Can't call useEffectContext out of Effect runtime scope");
31
+ return context;
32
+ };
33
+ const useOperationContext = ()=>useEffectContext().operationContext;
34
+ export { createEffectOperationContext } from "./operation-context.mjs";
35
+ export { runWithEffectContext, useEffectContext, useOperationContext };
@@ -1,5 +1,6 @@
1
1
  import "node:module";
2
2
  import { createSafeFailureResponse } from "../safe-failure.mjs";
3
+ import { runWithEffectContext, useEffectContext, useOperationContext } from "./edge-context.mjs";
3
4
  import { resolveEffectBffModuleHandler } from "./module.mjs";
4
5
  import { createEffectOperationContext } from "./operation-context.mjs";
5
6
  export * from "./handler.mjs";
@@ -51,7 +52,7 @@ async function dispatchEffectBffRequest(handler, request, options = {}) {
51
52
  const effectRequest = createRequestForMountedPrefix(request, options.prefix);
52
53
  const effectContext = createEdgeEffectContext(request, effectRequest, options);
53
54
  try {
54
- const response = handler.length > 1 ? await handler(effectRequest, effectContext) : await handler(effectRequest);
55
+ const response = await runWithEffectContext(effectContext, ()=>handler.length > 1 ? handler(effectRequest, effectContext) : handler(effectRequest));
55
56
  if (!(response instanceof Response)) throw new Error('[BFF][Effect] Effect handler must return a Response instance.');
56
57
  return new Response(response.body, response);
57
58
  } catch (error) {
@@ -63,6 +64,7 @@ async function dispatchEffectBffRequest(handler, request, options = {}) {
63
64
  return createRuntimeErrorResponse(error);
64
65
  }
65
66
  }
67
+ const createEffectBffTestHandler = createEffectBffEdgeHandler;
66
68
  async function createEffectBffEdgeHandler(options) {
67
69
  const loaded = await resolveEffectBffModuleHandler(options.module, {
68
70
  openapi: options.openapi,
@@ -81,4 +83,4 @@ async function createEffectBffEdgeHandler(options) {
81
83
  }
82
84
  };
83
85
  }
84
- export { createEffectBffEdgeHandler, createEffectOperationContext, dispatchEffectBffRequest };
86
+ export { createEffectBffEdgeHandler, createEffectBffTestHandler, createEffectOperationContext, dispatchEffectBffRequest, runWithEffectContext, useEffectContext, useOperationContext };
@@ -13,6 +13,8 @@ export * from "effect/unstable/httpapi";
13
13
  export * from "effect/unstable/rpc";
14
14
  import * as __rspack_external_effect_Context_f1289ca3 from "effect/Context";
15
15
  const emptyEffectServiceContext = __rspack_external_effect_Context_f1289ca3.empty();
16
+ const isEffectServiceContext = (context)=>'object' == typeof context && null !== context && 'mapUnsafe' in context;
17
+ const toEffectServiceContext = (context)=>isEffectServiceContext(context) ? context : emptyEffectServiceContext;
16
18
  const EFFECT_VALIDATOR_AWARE_FACTORY = Symbol.for('modernjs.effect.validatorAware');
17
19
  function isValidatorAwareHandlerFactory(factory) {
18
20
  return 'function' == typeof factory && true === factory[EFFECT_VALIDATOR_AWARE_FACTORY];
@@ -371,7 +373,7 @@ function createHttpApiHandler(options) {
371
373
  if (preparedRequest instanceof Response) return preparedRequest;
372
374
  const validationError = validateDataPlatformRequestEnvelope(preparedRequest, options.dataPlatform);
373
375
  if (validationError) return validationError;
374
- return httpApiHandler.handler(preparedRequest, context ?? emptyEffectServiceContext);
376
+ return httpApiHandler.handler(preparedRequest, toEffectServiceContext(context));
375
377
  };
376
378
  const handleBatchRequest = async (request, context)=>{
377
379
  const mountedPrefix = getMountedPrefixFromContext(request, context);
@@ -493,7 +495,7 @@ function createHttpApiHandler(options) {
493
495
  if (isRpcRequest(request, rpcPath)) {
494
496
  const policyDenial = options.validateRequest?.(request);
495
497
  if (policyDenial) return policyDenial;
496
- return rpcHandler.handler(request, context ?? emptyEffectServiceContext);
498
+ return rpcHandler.handler(request, toEffectServiceContext(context));
497
499
  }
498
500
  return handleHttpApiRequest(request);
499
501
  },
@@ -1,5 +1,6 @@
1
1
  import "node:module";
2
2
  import * as __rspack_external__effect_opentelemetry_8bbbb5af from "@effect/opentelemetry";
3
3
  export * from "./handler.mjs";
4
- export { createEffectOperationContext, useEffectContext, useOperationContext } from "./context.mjs";
4
+ export { createEffectOperationContext, runWithEffectContext, useEffectContext, useOperationContext } from "./context.mjs";
5
+ export { createEffectBffEdgeHandler, createEffectBffTestHandler, dispatchEffectBffRequest } from "./edge.mjs";
5
6
  export { __rspack_external__effect_opentelemetry_8bbbb5af as OpenTelemetry };
@@ -4,7 +4,7 @@ import path from "path";
4
4
  import { API_DIR, DIST_DIR, LAMBDA_DIR, PACKAGE_NAME, PREFIX, RUNTIME_FRAMEWORK } from "./crossProjectApiPlugin.mjs";
5
5
  import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
6
6
  import { dirname as __rspack_dirname } from "node:path";
7
- var pluginGenerator_dirname = __rspack_dirname(__rspack_fileURLToPath(import.meta.url));
7
+ var __rspack_import_meta_dirname__ = __rspack_dirname(__rspack_fileURLToPath(import.meta.url));
8
8
  function replaceContent(source, packageName, prefix, relativeDistPath, relativeApiPath, relativeLambdaPath, runtimeFramework) {
9
9
  const updatedSource = source.replace(new RegExp(PACKAGE_NAME, 'g'), packageName).replace(new RegExp(PREFIX, 'g'), prefix).replace(new RegExp(DIST_DIR, 'g'), normalizeToPosixPath(relativeDistPath)).replace(new RegExp(API_DIR, 'g'), normalizeToPosixPath(relativeApiPath)).replace(new RegExp(LAMBDA_DIR, 'g'), normalizeToPosixPath(relativeLambdaPath)).replace(new RegExp(RUNTIME_FRAMEWORK, 'g'), runtimeFramework);
10
10
  return updatedSource;
@@ -15,7 +15,7 @@ async function pluginGenerator({ prefix, appDirectory, relativeDistPath, relativ
15
15
  const packageJson = JSON.parse(packageContent);
16
16
  const pluginDir = path.resolve(appDirectory, `./${relativeDistPath}`, 'plugin');
17
17
  const pluginPath = path.join(pluginDir, 'index.js');
18
- const pluginTemplate = await fs.readFile(path.resolve(pluginGenerator_dirname, 'crossProjectApiPlugin.js'), 'utf8');
18
+ const pluginTemplate = await fs.readFile(path.resolve(__rspack_import_meta_dirname__, 'crossProjectApiPlugin.js'), 'utf8');
19
19
  const updatedPlugin = replaceContent(pluginTemplate, packageJson.name, prefix, relativeDistPath, relativeApiPath, relativeLambdaPath, runtimeFramework);
20
20
  await fs.ensureFile(pluginPath);
21
21
  await fs.writeFile(pluginPath, updatedPlugin);
@@ -0,0 +1,5 @@
1
+ import type { EffectContext } from './operation-context';
2
+ export { type CreateEffectOperationContextOptions, createEffectOperationContext, type EffectContext, } from './operation-context';
3
+ export declare const runWithEffectContext: <T>(context: EffectContext, cb: () => T) => T;
4
+ export declare const useEffectContext: () => EffectContext;
5
+ export declare const useOperationContext: () => import("@modern-js/create-request").OperationContext;
@@ -1,6 +1,7 @@
1
1
  import type { EffectBffOpenApiConfig, EffectDataPlatformValidationOptions } from './handler';
2
2
  import { type EffectApiModule, type EffectBffRequestHandler } from './module';
3
3
  import { type EffectContext } from './operation-context';
4
+ export { runWithEffectContext, useEffectContext, useOperationContext, } from './edge-context';
4
5
  export * from './handler';
5
6
  export { type CreateEffectOperationContextOptions, createEffectOperationContext, type EffectContext, } from './operation-context';
6
7
  export type EffectBffEdgeDispatchOptions = {
@@ -19,6 +20,7 @@ export type EffectBffEdgeHandlerOptions = {
19
20
  onWarning?: (message: string) => void;
20
21
  };
21
22
  export declare function dispatchEffectBffRequest(handler: EffectBffRequestHandler, request: Request, options?: EffectBffEdgeDispatchOptions): Promise<Response>;
23
+ export declare const createEffectBffTestHandler: typeof createEffectBffEdgeHandler;
22
24
  export declare function createEffectBffEdgeHandler(options: EffectBffEdgeHandlerOptions): Promise<{
23
25
  handler: (request: Request, dispatchOptions?: Omit<EffectBffEdgeDispatchOptions, 'prefix' | 'onError'>) => Promise<Response>;
24
26
  dispose: () => Promise<void>;
@@ -1,3 +1,4 @@
1
1
  export * as OpenTelemetry from '@effect/opentelemetry';
2
- export { type CreateEffectOperationContextOptions, createEffectOperationContext, type EffectContext, useEffectContext, useOperationContext, } from './context';
2
+ export { type CreateEffectOperationContextOptions, createEffectOperationContext, type EffectContext, runWithEffectContext, useEffectContext, useOperationContext, } from './context';
3
+ export { createEffectBffEdgeHandler, createEffectBffTestHandler, dispatchEffectBffRequest, } from './edge';
3
4
  export * from './handler';
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "modern",
18
18
  "modern.js"
19
19
  ],
20
- "version": "3.5.0-ultramodern.0",
20
+ "version": "3.5.0-ultramodern.2",
21
21
  "types": "./dist/types/cli.d.ts",
22
22
  "main": "./dist/cjs/cli.js",
23
23
  "exports": {
@@ -142,7 +142,7 @@
142
142
  }
143
143
  },
144
144
  "dependencies": {
145
- "@effect/opentelemetry": "4.0.0-beta.89",
145
+ "@effect/opentelemetry": "4.0.0-beta.91",
146
146
  "@opentelemetry/api": "1.9.1",
147
147
  "@opentelemetry/api-logs": "0.219.0",
148
148
  "@opentelemetry/resources": "2.8.0",
@@ -154,31 +154,31 @@
154
154
  "@opentelemetry/semantic-conventions": "1.41.1",
155
155
  "@swc/core": "1.15.43",
156
156
  "@swc/helpers": "^0.5.23",
157
- "effect": "4.0.0-beta.89",
157
+ "effect": "4.0.0-beta.91",
158
158
  "qs": "^6.15.3",
159
159
  "type-is": "^2.1.0",
160
- "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.5.0-ultramodern.0",
161
- "@modern-js/create-request": "npm:@bleedingdev/modern-js-create-request@3.5.0-ultramodern.0",
162
- "@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.5.0-ultramodern.0",
163
- "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.5.0-ultramodern.0",
164
- "@modern-js/server-utils": "npm:@bleedingdev/modern-js-server-utils@3.5.0-ultramodern.0",
165
- "@modern-js/bff-core": "npm:@bleedingdev/modern-js-bff-core@3.5.0-ultramodern.0"
160
+ "@modern-js/bff-core": "npm:@bleedingdev/modern-js-bff-core@3.5.0-ultramodern.2",
161
+ "@modern-js/create-request": "npm:@bleedingdev/modern-js-create-request@3.5.0-ultramodern.2",
162
+ "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.5.0-ultramodern.2",
163
+ "@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.5.0-ultramodern.2",
164
+ "@modern-js/server-utils": "npm:@bleedingdev/modern-js-server-utils@3.5.0-ultramodern.2",
165
+ "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.5.0-ultramodern.2"
166
166
  },
167
167
  "devDependencies": {
168
- "@rsbuild/core": "2.1.0",
169
- "@rslib/core": "0.23.0",
168
+ "@rsbuild/core": "2.1.1",
169
+ "@rslib/core": "0.23.1",
170
170
  "@types/node": "^26.0.1",
171
171
  "@types/qs": "^6.15.1",
172
172
  "@types/type-is": "^1.6.7",
173
- "@typescript/native-preview": "7.0.0-dev.20260624.1",
173
+ "@typescript/native-preview": "7.0.0-dev.20260628.1",
174
174
  "memfs": "^4.57.8",
175
175
  "typescript": "^6.0.3",
176
176
  "zod": "^4.4.3",
177
- "@modern-js/app-tools": "npm:@bleedingdev/modern-js-app-tools@3.5.0-ultramodern.0",
178
- "@modern-js/bff-runtime": "npm:@bleedingdev/modern-js-bff-runtime@3.5.0-ultramodern.0",
179
- "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.5.0-ultramodern.0",
180
- "@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.5.0-ultramodern.0",
181
- "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.5.0-ultramodern.0",
177
+ "@modern-js/app-tools": "npm:@bleedingdev/modern-js-app-tools@3.5.0-ultramodern.2",
178
+ "@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.5.0-ultramodern.2",
179
+ "@modern-js/bff-runtime": "npm:@bleedingdev/modern-js-bff-runtime@3.5.0-ultramodern.2",
180
+ "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.5.0-ultramodern.2",
181
+ "@modern-js/runtime": "npm:@bleedingdev/modern-js-runtime@3.5.0-ultramodern.2",
182
182
  "@scripts/rstest-config": "2.66.0"
183
183
  },
184
184
  "sideEffects": false,