@bleedingdev/modern-js-bff-effect 3.9.0-ultramodern.2 → 3.9.0-ultramodern.21

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.
Files changed (142) hide show
  1. package/README.md +20 -4
  2. package/dist/cjs/assembly.js +50 -0
  3. package/dist/cjs/{effect-client/guards.js → data-platform/batch/options.js} +13 -9
  4. package/dist/cjs/data-platform/batch/queue.js +48 -83
  5. package/dist/cjs/data-platform/trace.js +2 -2
  6. package/dist/cjs/effect/context.js +28 -4
  7. package/dist/cjs/effect/edge-dispatcher.js +12 -12
  8. package/dist/cjs/effect/edge.js +36 -3
  9. package/dist/cjs/effect/endpoint-contracts.js +3 -4
  10. package/dist/cjs/effect/entry-shape.js +40 -12
  11. package/dist/cjs/effect/generated-entry.js +57 -0
  12. package/dist/cjs/effect/handler/batch-handler.js +7 -7
  13. package/dist/cjs/effect/handler/batch.js +8 -10
  14. package/dist/cjs/effect/handler/definition.js +1 -21
  15. package/dist/cjs/effect/index.js +8 -8
  16. package/dist/cjs/effect/module.js +8 -4
  17. package/dist/cjs/effect/operation-context.js +10 -14
  18. package/dist/cjs/effect/rpcSerialization.js +0 -2
  19. package/dist/cjs/effect-client/cross-project.js +89 -0
  20. package/dist/cjs/effect-client/index.js +5 -3
  21. package/dist/cjs/microvertical-api.js +120 -0
  22. package/dist/esm/assembly.mjs +12 -0
  23. package/dist/esm/data-platform/batch/options.mjs +10 -0
  24. package/dist/esm/data-platform/batch/queue.mjs +48 -83
  25. package/dist/esm/data-platform/trace.mjs +1 -1
  26. package/dist/esm/effect/context.mjs +21 -6
  27. package/dist/esm/effect/edge-dispatcher.mjs +6 -6
  28. package/dist/esm/effect/edge.mjs +3 -0
  29. package/dist/esm/effect/endpoint-contracts.mjs +2 -3
  30. package/dist/esm/effect/entry-shape-registry.mjs +2 -2
  31. package/dist/esm/effect/entry-shape.mjs +29 -6
  32. package/dist/esm/effect/generated-entry.mjs +19 -0
  33. package/dist/esm/effect/handler/batch-handler.mjs +8 -8
  34. package/dist/esm/effect/handler/batch.mjs +9 -8
  35. package/dist/esm/effect/handler/definition.mjs +1 -21
  36. package/dist/esm/effect/index.mjs +1 -1
  37. package/dist/esm/effect/module.mjs +8 -4
  38. package/dist/esm/effect/operation-context.mjs +3 -4
  39. package/dist/esm/effect/rpcSerialization.mjs +0 -2
  40. package/dist/esm/effect-client/cross-project.mjs +51 -0
  41. package/dist/esm/effect-client/index.mjs +4 -2
  42. package/dist/esm/microvertical-api.mjs +67 -0
  43. package/dist/esm-node/assembly.mjs +13 -0
  44. package/dist/esm-node/data-platform/batch/options.mjs +11 -0
  45. package/dist/esm-node/data-platform/batch/queue.mjs +48 -83
  46. package/dist/esm-node/data-platform/trace.mjs +1 -1
  47. package/dist/esm-node/effect/context.mjs +21 -6
  48. package/dist/esm-node/effect/edge-dispatcher.mjs +6 -6
  49. package/dist/esm-node/effect/edge.mjs +3 -0
  50. package/dist/esm-node/effect/endpoint-contracts.mjs +2 -3
  51. package/dist/esm-node/effect/entry-shape.mjs +29 -6
  52. package/dist/esm-node/effect/generated-entry.mjs +20 -0
  53. package/dist/esm-node/effect/handler/batch-handler.mjs +8 -8
  54. package/dist/esm-node/effect/handler/batch.mjs +9 -8
  55. package/dist/esm-node/effect/handler/definition.mjs +1 -21
  56. package/dist/esm-node/effect/index.mjs +1 -1
  57. package/dist/esm-node/effect/module.mjs +8 -4
  58. package/dist/esm-node/effect/operation-context.mjs +3 -4
  59. package/dist/esm-node/effect/rpcSerialization.mjs +0 -2
  60. package/dist/esm-node/effect-client/cross-project.mjs +52 -0
  61. package/dist/esm-node/effect-client/index.mjs +4 -2
  62. package/dist/esm-node/microvertical-api.mjs +68 -0
  63. package/dist/types/assembly.d.ts +10 -0
  64. package/dist/types/data-platform/batch/options.d.ts +7 -0
  65. package/dist/types/data-platform/batch/queue.d.ts +0 -1
  66. package/dist/types/effect/context.d.ts +15 -2
  67. package/dist/types/effect/edge-dispatcher.d.ts +3 -3
  68. package/dist/types/effect/edge.d.ts +3 -0
  69. package/dist/types/effect/endpoint-contracts.d.ts +2 -20
  70. package/dist/types/effect/entry-shape.d.ts +16 -2
  71. package/dist/types/effect/generated-entry.d.ts +7 -0
  72. package/dist/types/effect/handler/batch.d.ts +7 -2
  73. package/dist/types/effect/handler/types.d.ts +2 -17
  74. package/dist/types/effect/handler.d.ts +1 -1
  75. package/dist/types/effect/module.d.ts +2 -1
  76. package/dist/types/effect/operation-context.d.ts +1 -2
  77. package/dist/types/effect-client/cross-project.d.ts +10 -0
  78. package/dist/types/effect-client/index.d.ts +7 -4
  79. package/dist/types/microvertical-api.d.ts +65 -0
  80. package/package.json +47 -42
  81. package/src/assembly.ts +43 -0
  82. package/src/data-platform/batch/options.ts +20 -0
  83. package/src/data-platform/batch/queue.ts +63 -92
  84. package/src/data-platform/trace.ts +1 -1
  85. package/src/effect/context.ts +64 -12
  86. package/src/effect/edge-dispatcher.ts +14 -11
  87. package/src/effect/edge.ts +6 -0
  88. package/src/effect/endpoint-contracts.ts +3 -24
  89. package/src/effect/entry-shape.ts +105 -10
  90. package/src/effect/generated-entry.ts +36 -0
  91. package/src/effect/handler/batch-handler.ts +27 -28
  92. package/src/effect/handler/batch.ts +9 -13
  93. package/src/effect/handler/definition.ts +0 -45
  94. package/src/effect/handler/http.ts +2 -2
  95. package/src/effect/handler/types.ts +3 -32
  96. package/src/effect/handler.ts +0 -1
  97. package/src/effect/index.ts +1 -1
  98. package/src/effect/module.ts +11 -4
  99. package/src/effect/operation-context.ts +2 -6
  100. package/src/effect/rpcSerialization.ts +0 -2
  101. package/src/effect-client/cross-project.ts +104 -0
  102. package/src/effect-client/index.ts +17 -7
  103. package/src/microvertical-api.ts +102 -0
  104. package/dist/cjs/effect/edge-context.js +0 -61
  105. package/dist/cjs/effect-client/batch.js +0 -73
  106. package/dist/cjs/effect-client/envelope.js +0 -145
  107. package/dist/cjs/effect-client/request-context.js +0 -64
  108. package/dist/cjs/effect-client/request.js +0 -66
  109. package/dist/cjs/effect-client/runtime.js +0 -100
  110. package/dist/cjs/effect-client/types.js +0 -18
  111. package/dist/esm/effect/edge-context.mjs +0 -14
  112. package/dist/esm/effect-client/batch.mjs +0 -35
  113. package/dist/esm/effect-client/envelope.mjs +0 -104
  114. package/dist/esm/effect-client/guards.mjs +0 -3
  115. package/dist/esm/effect-client/request-context.mjs +0 -23
  116. package/dist/esm/effect-client/request.mjs +0 -28
  117. package/dist/esm/effect-client/runtime.mjs +0 -62
  118. package/dist/esm/effect-client/types.mjs +0 -0
  119. package/dist/esm-node/effect/edge-context.mjs +0 -15
  120. package/dist/esm-node/effect-client/batch.mjs +0 -36
  121. package/dist/esm-node/effect-client/envelope.mjs +0 -105
  122. package/dist/esm-node/effect-client/guards.mjs +0 -4
  123. package/dist/esm-node/effect-client/request-context.mjs +0 -24
  124. package/dist/esm-node/effect-client/request.mjs +0 -29
  125. package/dist/esm-node/effect-client/runtime.mjs +0 -63
  126. package/dist/esm-node/effect-client/types.mjs +0 -1
  127. package/dist/types/effect/edge-context.d.ts +0 -5
  128. package/dist/types/effect-client/batch.d.ts +0 -2
  129. package/dist/types/effect-client/envelope.d.ts +0 -15
  130. package/dist/types/effect-client/guards.d.ts +0 -2
  131. package/dist/types/effect-client/request-context.d.ts +0 -3
  132. package/dist/types/effect-client/request.d.ts +0 -1
  133. package/dist/types/effect-client/runtime.d.ts +0 -5
  134. package/dist/types/effect-client/types.d.ts +0 -68
  135. package/src/effect/edge-context.ts +0 -51
  136. package/src/effect-client/batch.ts +0 -50
  137. package/src/effect-client/envelope.ts +0 -238
  138. package/src/effect-client/guards.ts +0 -6
  139. package/src/effect-client/request-context.ts +0 -54
  140. package/src/effect-client/request.ts +0 -51
  141. package/src/effect-client/runtime.ts +0 -122
  142. package/src/effect-client/types.ts +0 -84
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # @modern-js/bff-effect
2
2
 
3
3
  Fork-owned Effect primitives for UltraModern.js BFF runtimes. The package
4
- keeps the portable Effect handler, data-platform, generated-client runtime,
4
+ keeps the portable Effect handler, data-platform, native inferred clients,
5
5
  and edge dispatcher behind standalone package entry points rather than growing
6
6
  the upstream-owned `@modern-js/plugin-bff` implementation.
7
7
 
@@ -16,10 +16,26 @@ upstream Modern.js project.
16
16
  - `@modern-js/bff-effect/effect-edge` exposes the edge-safe dispatcher without
17
17
  a static Node built-in import.
18
18
  - `@modern-js/bff-effect/effect-client` exposes the Effect client runtime.
19
- - `@modern-js/bff-effect/effect-client-runtime` exposes the generated-client
20
- runtime helpers.
21
19
  - `@modern-js/bff-effect/data-platform` exposes batching, envelope, tracing,
22
20
  validation, and invalidation primitives.
23
21
 
24
- Adapter lifecycle integration, Hono integration, source/client generation, and
22
+ Adapter lifecycle integration, Hono integration, server source loading, and
25
23
  backend federation are intentionally owned by their respective packages.
24
+
25
+ ## HTTP clients
26
+
27
+ Keep the `HttpApi` contract in a shared module and pass it to Effect's
28
+ `HttpApiClient.make` or `makeEffectHttpApiClient` from `/effect-client`.
29
+ Requests, responses, and declared errors are inferred from that contract.
30
+ No SDK generation or backend-entry import is required.
31
+
32
+ `defineEffectBff` creates server handlers. Its former `client` placeholder,
33
+ the `@api/index` client transform, and `/effect-client-runtime` have been
34
+ removed. Move consumers to the shared contract and execute native client
35
+ operations with Effect.
36
+
37
+ For APIs hosted through a cross-project plugin, pass `crossProject` to the
38
+ native client helper: `{ requestId: 'catalog', operationVersion: 2, prefix: '/api' }`.
39
+ Use the producer's request ID, package major version, and server mount path.
40
+ Effect HTTP middleware derives operation headers from the shared contract;
41
+ the server continues to reject missing or stale contract headers.
@@ -0,0 +1,50 @@
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
+ assembleEffectBffRuntime: ()=>assembleEffectBffRuntime
32
+ });
33
+ const Layer_namespaceObject = require("effect/Layer");
34
+ const httpapi_namespaceObject = require("effect/unstable/httpapi");
35
+ const definition_js_namespaceObject = require("./effect/handler/definition.js");
36
+ const assembleEffectBffRuntime = ({ api, handlers, transport })=>{
37
+ const apiLayer = httpapi_namespaceObject.HttpApiBuilder.layer(api).pipe(Layer_namespaceObject.provide(handlers));
38
+ const layer = void 0 === transport ? apiLayer : apiLayer.pipe(Layer_namespaceObject.merge(transport));
39
+ return (0, definition_js_namespaceObject.defineEffectBff)({
40
+ api,
41
+ layer
42
+ });
43
+ };
44
+ exports.assembleEffectBffRuntime = __webpack_exports__.assembleEffectBffRuntime;
45
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
46
+ "assembleEffectBffRuntime"
47
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
48
+ Object.defineProperty(exports, '__esModule', {
49
+ value: true
50
+ });
@@ -27,17 +27,21 @@ var __webpack_require__ = {};
27
27
  })();
28
28
  var __webpack_exports__ = {};
29
29
  __webpack_require__.r(__webpack_exports__);
30
- const isRecord = (value)=>'object' == typeof value && null !== value;
31
- const stringOrUndefined = (value)=>'string' == typeof value && value.length > 0 ? value : void 0;
32
- __webpack_require__.d(__webpack_exports__, {}, {
33
- isRecord: isRecord,
34
- stringOrUndefined: stringOrUndefined
30
+ function normalizeBatchLimits(options = {}) {
31
+ return {
32
+ maxBatchSize: Math.max(1, options.maxBatchSize ?? 16),
33
+ maxBatchBytes: Math.max(1024, options.maxBatchBytes ?? 65536),
34
+ allowedMethods: new Set((void 0 !== options.allowedMethods && options.allowedMethods.length > 0 ? options.allowedMethods : [
35
+ 'GET'
36
+ ]).map((method)=>method.toUpperCase()))
37
+ };
38
+ }
39
+ __webpack_require__.d(__webpack_exports__, {
40
+ normalizeBatchLimits: ()=>normalizeBatchLimits
35
41
  });
36
- exports.isRecord = __webpack_exports__.isRecord;
37
- exports.stringOrUndefined = __webpack_exports__.stringOrUndefined;
42
+ exports.normalizeBatchLimits = __webpack_exports__.normalizeBatchLimits;
38
43
  for(var __rspack_i in __webpack_exports__)if (-1 === [
39
- "isRecord",
40
- "stringOrUndefined"
44
+ "normalizeBatchLimits"
41
45
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
42
46
  Object.defineProperty(exports, '__esModule', {
43
47
  value: true
@@ -33,6 +33,7 @@ __webpack_require__.d(__webpack_exports__, {
33
33
  });
34
34
  const external_codec_js_namespaceObject = require("../codec.js");
35
35
  const external_types_js_namespaceObject = require("../types.js");
36
+ const external_options_js_namespaceObject = require("./options.js");
36
37
  const external_protocol_js_namespaceObject = require("./protocol.js");
37
38
  const external_request_js_namespaceObject = require("./request.js");
38
39
  const external_response_js_namespaceObject = require("./response.js");
@@ -111,7 +112,6 @@ class BatchBucketRegistry {
111
112
  if (existing) return existing;
112
113
  const next = {
113
114
  items: [],
114
- bytes: 0,
115
115
  batchId: (0, external_request_js_namespaceObject.createBatchId)(),
116
116
  sentAt: Date.now(),
117
117
  timer: null,
@@ -130,12 +130,8 @@ class BatchBucketRegistry {
130
130
  }
131
131
  function createBatchTransportQueue({ options, baseFetch, bucketRegistry }) {
132
132
  const flushIntervalMs = Math.max(0, options.flushIntervalMs ?? 8);
133
- const maxBatchSize = Math.max(1, options.maxBatchSize ?? 16);
134
- const maxBatchBytes = Math.max(1024, options.maxBatchBytes ?? 65536);
133
+ const { maxBatchSize, maxBatchBytes, allowedMethods } = (0, external_options_js_namespaceObject.normalizeBatchLimits)(options);
135
134
  const requestTimeoutMs = options.requestTimeoutMs;
136
- const allowedMethods = new Set((options.allowedMethods && options.allowedMethods.length > 0 ? options.allowedMethods : [
137
- 'GET'
138
- ]).map((method)=>method.toUpperCase()));
139
135
  const onEvent = options.onEvent;
140
136
  const buckets = bucketRegistry ?? new BatchBucketRegistry();
141
137
  const pendingByKey = new Map();
@@ -168,7 +164,6 @@ function createBatchTransportQueue({ options, baseFetch, bucketRegistry }) {
168
164
  const index = bucket.items.indexOf(request);
169
165
  if (-1 === index) return;
170
166
  bucket.items.splice(index, 1);
171
- bucket.bytes = measurePayload(bucket, bucket.items);
172
167
  if (0 === bucket.items.length && bucket.timer) {
173
168
  clearTimeout(bucket.timer);
174
169
  bucket.timer = null;
@@ -210,7 +205,11 @@ function createBatchTransportQueue({ options, baseFetch, bucketRegistry }) {
210
205
  if (!SAFE_REPLAY_METHODS.has(request.item.method)) throw new Error(`Batch result is unknown for ${request.item.method}; automatic replay is disabled (${reason}).`);
211
206
  return runSingle(request);
212
207
  };
213
- const settleAmbiguousBatchRequests = (items, reason)=>settleRequests(items, (request)=>runAfterAmbiguousBatch(request, reason));
208
+ const finishFlush = (bucketKey, bucket)=>{
209
+ bucket.flushing = false;
210
+ if (bucket.items.length > 0 && !bucket.timer) flushBucket(bucketKey);
211
+ buckets.releaseIfIdle(bucketKey, bucket);
212
+ };
214
213
  const flushBucket = async (bucketKey)=>{
215
214
  const bucket = buckets.get(bucketKey);
216
215
  if (!bucket || bucket.flushing) return;
@@ -227,7 +226,6 @@ function createBatchTransportQueue({ options, baseFetch, bucketRegistry }) {
227
226
  sentAt: bucket.sentAt
228
227
  };
229
228
  bucket.items = [];
230
- bucket.bytes = 0;
231
229
  rotatePayloadIdentity(bucket);
232
230
  const firstItem = items[0];
233
231
  if (!firstItem) {
@@ -243,14 +241,25 @@ function createBatchTransportQueue({ options, baseFetch, bucketRegistry }) {
243
241
  size: items.length,
244
242
  reason: disabledEndpoints.has(endpoint) ? 'batch-disabled' : void 0
245
243
  });
246
- await settleRequests(items, runSingle);
247
- bucket.flushing = false;
248
- if (bucket.items.length > 0 && !bucket.timer) flushBucket(bucketKey);
249
- buckets.releaseIfIdle(bucketKey, bucket);
244
+ try {
245
+ await settleRequests(items, runSingle);
246
+ } finally{
247
+ finishFlush(bucketKey, bucket);
248
+ }
250
249
  return;
251
250
  }
252
251
  const payload = createPayload(payloadIdentity, items);
253
252
  const batchId = payload.batchId;
253
+ const settleAmbiguousBatchRequests = (reason)=>{
254
+ (0, external_telemetry_js_namespaceObject.emitDataBatchTransportEvent)(onEvent, {
255
+ type: 'fallback',
256
+ endpoint,
257
+ batchId,
258
+ size: items.length,
259
+ reason
260
+ });
261
+ return settleRequests(items, (request)=>runAfterAmbiguousBatch(request, reason));
262
+ };
254
263
  (0, external_telemetry_js_namespaceObject.emitDataBatchTransportEvent)(onEvent, {
255
264
  type: 'flush',
256
265
  endpoint,
@@ -301,42 +310,13 @@ function createBatchTransportQueue({ options, baseFetch, bucketRegistry }) {
301
310
  batchId,
302
311
  reason: `batch-endpoint-unavailable-${String(response.status)}`
303
312
  });
304
- } else (0, external_telemetry_js_namespaceObject.emitDataBatchTransportEvent)(onEvent, {
305
- type: 'fallback',
306
- endpoint,
307
- batchId,
308
- size: items.length,
309
- reason: `batch-response-${String(response.status)}`
310
- });
311
- await settleAmbiguousBatchRequests(items, `batch-response-${String(response.status)}`);
312
- bucket.flushing = false;
313
+ await settleRequests(items, (request)=>runAfterAmbiguousBatch(request, `batch-response-${String(response.status)}`));
314
+ } else await settleAmbiguousBatchRequests(`batch-response-${String(response.status)}`);
313
315
  return;
314
316
  }
315
317
  const result = await runWithSignal(controller.signal, async ()=>response.json());
316
- if (!(0, external_response_js_namespaceObject.isBatchResponsePayload)(result)) {
317
- (0, external_telemetry_js_namespaceObject.emitDataBatchTransportEvent)(onEvent, {
318
- type: 'fallback',
319
- endpoint,
320
- batchId,
321
- size: items.length,
322
- reason: 'invalid-batch-response'
323
- });
324
- await settleAmbiguousBatchRequests(items, 'invalid-batch-response');
325
- bucket.flushing = false;
326
- return;
327
- }
328
- if (result.batchId !== batchId) {
329
- (0, external_telemetry_js_namespaceObject.emitDataBatchTransportEvent)(onEvent, {
330
- type: 'fallback',
331
- endpoint,
332
- batchId,
333
- size: items.length,
334
- reason: 'mismatched-batch-id'
335
- });
336
- await settleAmbiguousBatchRequests(items, 'mismatched-batch-id');
337
- bucket.flushing = false;
338
- return;
339
- }
318
+ if (!(0, external_response_js_namespaceObject.isBatchResponsePayload)(result)) return void await settleAmbiguousBatchRequests('invalid-batch-response');
319
+ if (result.batchId !== batchId) return void await settleAmbiguousBatchRequests('mismatched-batch-id');
340
320
  const itemMap = new Map();
341
321
  for (const item of result.items)itemMap.set(item.id, item);
342
322
  await settleRequests(items, async (request)=>{
@@ -360,19 +340,10 @@ function createBatchTransportQueue({ options, baseFetch, bucketRegistry }) {
360
340
  });
361
341
  return;
362
342
  }
363
- (0, external_telemetry_js_namespaceObject.emitDataBatchTransportEvent)(onEvent, {
364
- type: 'fallback',
365
- endpoint,
366
- batchId,
367
- size: items.length,
368
- reason: 'batch-transport-error'
369
- });
370
- await settleAmbiguousBatchRequests(items, 'batch-transport-error');
343
+ await settleAmbiguousBatchRequests('batch-transport-error');
371
344
  } finally{
372
345
  for (const item of items)item.abortBatchIfUnused = void 0;
373
- bucket.flushing = false;
374
- if (bucket.items.length > 0 && !bucket.timer) flushBucket(bucketKey);
375
- buckets.releaseIfIdle(bucketKey, bucket);
346
+ finishFlush(bucketKey, bucket);
376
347
  }
377
348
  };
378
349
  const pendingReadPromises = new Map();
@@ -396,7 +367,20 @@ function createBatchTransportQueue({ options, baseFetch, bucketRegistry }) {
396
367
  const sourceSignal = initDefinesSignal ? initSignal ?? void 0 : sourceRequest?.signal;
397
368
  const requestUrl = (0, external_url_js_namespaceObject.toAbsoluteUrl)(input);
398
369
  const endpoint = (0, external_url_js_namespaceObject.normalizeBatchEndpoint)(requestUrl, options.endpoint).toString();
370
+ const itemHeaders = {
371
+ ...headers
372
+ };
373
+ delete itemHeaders.authorization;
374
+ delete itemHeaders.cookie;
399
375
  return {
376
+ itemHeaders,
377
+ itemPath: `${requestUrl.pathname}${requestUrl.search}`,
378
+ bucketKey: (0, external_codec_js_namespaceObject.stableStringify)({
379
+ endpoint,
380
+ authorization: headers.authorization ?? null,
381
+ cookie: headers.cookie ?? null,
382
+ credentials
383
+ }),
400
384
  requestUrl,
401
385
  endpoint,
402
386
  method,
@@ -429,22 +413,11 @@ function createBatchTransportQueue({ options, baseFetch, bucketRegistry }) {
429
413
  batchEndpoint: request.endpoint,
430
414
  requestUrl: request.requestUrl
431
415
  })) return;
432
- const itemHeaders = {
433
- ...request.headers
434
- };
435
- delete itemHeaders.authorization;
436
- delete itemHeaders.cookie;
437
- const bucketKey = (0, external_codec_js_namespaceObject.stableStringify)({
438
- endpoint: request.endpoint,
439
- authorization: request.headers.authorization ?? null,
440
- cookie: request.headers.cookie ?? null,
441
- credentials: request.credentials
442
- });
443
416
  return (0, external_codec_js_namespaceObject.stableStringify)({
444
- bucketKey,
445
- path: `${request.requestUrl.pathname}${request.requestUrl.search}`,
417
+ bucketKey: request.bucketKey,
418
+ path: request.itemPath,
446
419
  method: request.method,
447
- headers: itemHeaders,
420
+ headers: request.itemHeaders,
448
421
  body: null
449
422
  });
450
423
  };
@@ -462,26 +435,19 @@ function createBatchTransportQueue({ options, baseFetch, bucketRegistry }) {
462
435
  const itemId = `${Date.now().toString(36)}_${nextItemId.toString(36)}_${Math.random().toString(16).slice(2, 8)}`;
463
436
  nextItemId += 1;
464
437
  const itemHeaders = {
465
- ...request.headers
438
+ ...request.itemHeaders
466
439
  };
467
- delete itemHeaders.authorization;
468
- delete itemHeaders.cookie;
469
440
  if (preparedBody.body && preparedBody.inferredContentType && !itemHeaders['content-type']) itemHeaders['content-type'] = preparedBody.inferredContentType;
470
441
  const item = {
471
442
  id: itemId,
472
- path: `${request.requestUrl.pathname}${request.requestUrl.search}`,
443
+ path: request.itemPath,
473
444
  method: request.method,
474
445
  headers: itemHeaders,
475
446
  ...preparedBody.body ? {
476
447
  body: preparedBody.body
477
448
  } : {}
478
449
  };
479
- const bucketKey = (0, external_codec_js_namespaceObject.stableStringify)({
480
- endpoint: request.endpoint,
481
- authorization: request.headers.authorization ?? null,
482
- cookie: request.headers.cookie ?? null,
483
- credentials: request.credentials
484
- });
450
+ const { bucketKey } = request;
485
451
  const key = (0, external_codec_js_namespaceObject.stableStringify)({
486
452
  bucketKey,
487
453
  path: item.path,
@@ -575,13 +541,12 @@ function createBatchTransportQueue({ options, baseFetch, bucketRegistry }) {
575
541
  }
576
542
  }
577
543
  bucket.items.push(queued);
578
- bucket.bytes = measurePayload(bucket, bucket.items);
579
544
  (0, external_telemetry_js_namespaceObject.emitDataBatchTransportEvent)(onEvent, {
580
545
  type: 'enqueue',
581
546
  endpoint: request.endpoint,
582
547
  size: bucket.items.length
583
548
  });
584
- if (bucket.items.length >= maxBatchSize || bucket.bytes >= maxBatchBytes) {
549
+ if (bucket.items.length >= maxBatchSize || measurePayload(bucket, bucket.items) >= maxBatchBytes) {
585
550
  flushBucket(bucketKey);
586
551
  return queued.promise;
587
552
  }
@@ -32,7 +32,7 @@ __webpack_require__.d(__webpack_exports__, {
32
32
  formatTraceparentHeader: ()=>formatTraceparentHeader,
33
33
  parseTraceparentHeader: ()=>parseTraceparentHeader
34
34
  });
35
- const create_request_namespaceObject = require("@modern-js/create-request");
35
+ const request_context_namespaceObject = require("@modern-js/runtime-extensions/request-context");
36
36
  function isAllZeroHex(value) {
37
37
  return /^0+$/.test(value);
38
38
  }
@@ -40,7 +40,7 @@ function isValidHex(value, length) {
40
40
  return value.length === length && /^[0-9a-f]+$/.test(value);
41
41
  }
42
42
  function parseTraceparentHeader(header) {
43
- return (0, create_request_namespaceObject.parseTraceparent)(header) ?? null;
43
+ return (0, request_context_namespaceObject.parseTraceparent)(header) ?? null;
44
44
  }
45
45
  function formatTraceparentHeader(trace) {
46
46
  const traceId = trace.traceId.toLowerCase();
@@ -28,28 +28,52 @@ var __webpack_require__ = {};
28
28
  var __webpack_exports__ = {};
29
29
  __webpack_require__.r(__webpack_exports__);
30
30
  __webpack_require__.d(__webpack_exports__, {
31
+ EFFECT_BFF_CONTEXT_STORAGE_SHARE: ()=>EFFECT_BFF_CONTEXT_STORAGE_SHARE,
32
+ adoptEffectContextStorage: ()=>adoptEffectContextStorage,
31
33
  createEffectOperationContext: ()=>external_operation_context_js_namespaceObject.createEffectOperationContext,
34
+ getEffectContextStorage: ()=>getEffectContextStorage,
32
35
  runWithEffectContext: ()=>runWithEffectContext,
33
36
  useEffectContext: ()=>useEffectContext,
34
37
  useOperationContext: ()=>useOperationContext
35
38
  });
36
- const external_node_async_hooks_namespaceObject = require("node:async_hooks");
37
39
  const external_operation_context_js_namespaceObject = require("./operation-context.js");
38
40
  const globalStore = globalThis;
39
- const effectContextStorage = globalStore[external_operation_context_js_namespaceObject.kEffectContextStorage] ?? (globalStore[external_operation_context_js_namespaceObject.kEffectContextStorage] = new external_node_async_hooks_namespaceObject.AsyncLocalStorage());
40
- const runWithEffectContext = (context, cb)=>effectContextStorage.run(context, cb);
41
+ const asyncHooks = globalStore.process?.getBuiltinModule?.('node:async_hooks');
42
+ const AsyncLocalStorage = asyncHooks?.AsyncLocalStorage;
43
+ if ('function' != typeof AsyncLocalStorage) throw new Error('[BFF][Effect] The edge runtime must provide AsyncLocalStorage. Enable Node.js compatibility or the nodejs_als compatibility flag.');
44
+ const EFFECT_BFF_CONTEXT_STORAGE_SHARE = '@modern-js/bff-effect/context-storage';
45
+ let effectContextStorage = new AsyncLocalStorage();
46
+ let effectContextStorageUsed = false;
47
+ const usedEffectContextStorage = ()=>{
48
+ effectContextStorageUsed = true;
49
+ return effectContextStorage;
50
+ };
51
+ const runWithEffectContext = (context, cb)=>usedEffectContextStorage().run(context, cb);
41
52
  const useEffectContext = ()=>{
42
- const context = effectContextStorage.getStore();
53
+ const context = usedEffectContextStorage().getStore();
43
54
  if (!context) throw new Error("Can't call useEffectContext out of Effect runtime scope");
44
55
  return context;
45
56
  };
57
+ const getEffectContextStorage = ()=>effectContextStorage;
58
+ function adoptEffectContextStorage(storage) {
59
+ const candidate = storage;
60
+ if ('function' != typeof candidate?.run || 'function' != typeof candidate.getStore) throw new Error(`[BFF][Effect] Share ${EFFECT_BFF_CONTEXT_STORAGE_SHARE} must provide an AsyncLocalStorage.`);
61
+ if (effectContextStorageUsed && candidate !== effectContextStorage) throw new Error('[BFF][Effect] A backend federation container received the host request storage after an Effect API already used its own. Evaluate exposes only after container init().');
62
+ effectContextStorage = candidate;
63
+ }
46
64
  const useOperationContext = ()=>useEffectContext().operationContext;
65
+ exports.EFFECT_BFF_CONTEXT_STORAGE_SHARE = __webpack_exports__.EFFECT_BFF_CONTEXT_STORAGE_SHARE;
66
+ exports.adoptEffectContextStorage = __webpack_exports__.adoptEffectContextStorage;
47
67
  exports.createEffectOperationContext = __webpack_exports__.createEffectOperationContext;
68
+ exports.getEffectContextStorage = __webpack_exports__.getEffectContextStorage;
48
69
  exports.runWithEffectContext = __webpack_exports__.runWithEffectContext;
49
70
  exports.useEffectContext = __webpack_exports__.useEffectContext;
50
71
  exports.useOperationContext = __webpack_exports__.useOperationContext;
51
72
  for(var __rspack_i in __webpack_exports__)if (-1 === [
73
+ "EFFECT_BFF_CONTEXT_STORAGE_SHARE",
74
+ "adoptEffectContextStorage",
52
75
  "createEffectOperationContext",
76
+ "getEffectContextStorage",
53
77
  "runWithEffectContext",
54
78
  "useEffectContext",
55
79
  "useOperationContext"
@@ -93,17 +93,17 @@ __webpack_require__.d(__webpack_exports__, {
93
93
  defineEffectBff: ()=>external_handler_js_namespaceObject.defineEffectBff,
94
94
  defineEffectRpcBff: ()=>external_handler_js_namespaceObject.defineEffectRpcBff,
95
95
  dispatchEffectBffRequest: ()=>dispatchEffectBffRequest,
96
- runWithEffectContext: ()=>external_edge_context_js_namespaceObject.runWithEffectContext,
97
- useEffectContext: ()=>external_edge_context_js_namespaceObject.useEffectContext,
98
- useOperationContext: ()=>external_edge_context_js_namespaceObject.useOperationContext
96
+ runWithEffectContext: ()=>context_namespaceObject.runWithEffectContext,
97
+ useEffectContext: ()=>context_namespaceObject.useEffectContext,
98
+ useOperationContext: ()=>context_namespaceObject.useOperationContext
99
99
  });
100
- const cross_project_policy_namespaceObject = require("@modern-js/bff-core/security/cross-project-policy");
100
+ const context_namespaceObject = require("@modern-js/bff-effect/context");
101
+ const bff_policy_namespaceObject = require("@modern-js/server-runtime-extensions/bff-policy");
102
+ const Effect_namespaceObject = require("effect/Effect");
101
103
  const external_headers_js_namespaceObject = require("../headers.js");
102
104
  const external_dispatch_js_namespaceObject = require("./dispatch.js");
103
- const external_edge_context_js_namespaceObject = require("./edge-context.js");
104
105
  const external_module_js_namespaceObject = require("./module.js");
105
106
  const Config_namespaceObject = require("effect/Config");
106
- const Effect_namespaceObject = require("effect/Effect");
107
107
  const Layer_namespaceObject = require("effect/Layer");
108
108
  const Option_namespaceObject = require("effect/Option");
109
109
  const Schema_namespaceObject = require("effect/Schema");
@@ -136,7 +136,7 @@ function restoreEffectBffMountPath(request, prefix) {
136
136
  async function dispatchEffectBffRequest(handler, request, options = {}) {
137
137
  return (0, external_dispatch_js_namespaceObject.dispatchEffectBffRequestWithContext)(handler, request, {
138
138
  ...options,
139
- runWithEffectContext: external_edge_context_js_namespaceObject.runWithEffectContext
139
+ runWithEffectContext: context_namespaceObject.runWithEffectContext
140
140
  });
141
141
  }
142
142
  async function createEffectBffEdgeDispatcher(options) {
@@ -147,14 +147,14 @@ async function createEffectBffEdgeDispatcher(options) {
147
147
  dataPlatform: options.dataPlatform,
148
148
  validateRequest: crossProjectPolicy?.enabled === true ? (request)=>{
149
149
  const pathname = new URL(request.url).pathname;
150
- const observedRequest = (0, cross_project_policy_namespaceObject.resolveCrossProjectRequestObservation)({
150
+ const observedRequest = (0, bff_policy_namespaceObject.resolveCrossProjectRequestObservation)({
151
151
  method: request.method,
152
152
  pathname
153
153
  }, crossProjectPolicy) ?? {
154
154
  method: request.method,
155
155
  routePath: restoreEffectBffMountPath(request, options.prefix)
156
156
  };
157
- const violation = (0, cross_project_policy_namespaceObject.evaluateCrossProjectPolicy)((0, external_headers_js_namespaceObject.toHeaderRecord)(request.headers), crossProjectPolicy, observedRequest);
157
+ const violation = (0, bff_policy_namespaceObject.evaluateCrossProjectPolicy)((0, external_headers_js_namespaceObject.toHeaderRecord)(request.headers), crossProjectPolicy, observedRequest);
158
158
  if (!violation) return null;
159
159
  return new Response(JSON.stringify({
160
160
  code: violation.code,
@@ -194,9 +194,9 @@ async function createEffectBffEdgeDispatcher(options) {
194
194
  dispose: ()=>{
195
195
  disposePromise ??= (async ()=>{
196
196
  acceptingRequests = false;
197
- if (activeDispatches > 0) await new Promise((resolve)=>{
198
- resolveDrain = resolve;
199
- });
197
+ if (activeDispatches > 0) await Effect_namespaceObject.runPromise(Effect_namespaceObject.callback((resume)=>{
198
+ resolveDrain = ()=>resume(Effect_namespaceObject["void"]);
199
+ }));
200
200
  await loaded.dispose?.();
201
201
  })();
202
202
  return disposePromise;
@@ -2,6 +2,15 @@
2
2
  var __webpack_modules__ = {
3
3
  "./edge-dispatcher" (module) {
4
4
  module.exports = require("./edge-dispatcher.js");
5
+ },
6
+ "./entry-shape" (module) {
7
+ module.exports = require("./entry-shape.js");
8
+ },
9
+ "./generated-entry" (module) {
10
+ module.exports = require("./generated-entry.js");
11
+ },
12
+ "@modern-js/bff-effect/context" (module) {
13
+ module.exports = require("@modern-js/bff-effect/context");
5
14
  }
6
15
  };
7
16
  var __webpack_module_cache__ = {};
@@ -51,12 +60,36 @@ function __webpack_require__(moduleId) {
51
60
  var __webpack_exports__ = {};
52
61
  (()=>{
53
62
  __webpack_require__.r(__webpack_exports__);
54
- var _edge_dispatcher__rspack_import_0 = __webpack_require__("./edge-dispatcher");
63
+ var _modern_js_bff_effect_context__rspack_import_0 = __webpack_require__("@modern-js/bff-effect/context");
64
+ var _edge_dispatcher__rspack_import_1 = __webpack_require__("./edge-dispatcher");
55
65
  var __rspack_reexport = {};
56
- for(const __rspack_import_key in _edge_dispatcher__rspack_import_0)if ("default" !== __rspack_import_key) __rspack_reexport[__rspack_import_key] = ()=>_edge_dispatcher__rspack_import_0[__rspack_import_key];
66
+ for(const __rspack_import_key in _edge_dispatcher__rspack_import_1)if ([
67
+ "EFFECT_BFF_CONTEXT_STORAGE_SHARE",
68
+ "default",
69
+ "EFFECT_BFF_HANDLER_FACTORY_REGISTRY_SHARE",
70
+ "createEffectBffEdgeDispatcherFactory",
71
+ "adoptEffectBffShareScope"
72
+ ].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>_edge_dispatcher__rspack_import_1[__rspack_import_key];
57
73
  __webpack_require__.d(__webpack_exports__, __rspack_reexport);
74
+ var _entry_shape__rspack_import_2 = __webpack_require__("./entry-shape");
75
+ var _generated_entry__rspack_import_3 = __webpack_require__("./generated-entry");
76
+ __webpack_require__.d(__webpack_exports__, {
77
+ EFFECT_BFF_CONTEXT_STORAGE_SHARE: ()=>_modern_js_bff_effect_context__rspack_import_0.EFFECT_BFF_CONTEXT_STORAGE_SHARE,
78
+ EFFECT_BFF_HANDLER_FACTORY_REGISTRY_SHARE: ()=>_entry_shape__rspack_import_2.EFFECT_BFF_HANDLER_FACTORY_REGISTRY_SHARE,
79
+ adoptEffectBffShareScope: ()=>_entry_shape__rspack_import_2.adoptEffectBffShareScope,
80
+ createEffectBffEdgeDispatcherFactory: ()=>_generated_entry__rspack_import_3.createEffectBffEdgeDispatcherFactory
81
+ });
58
82
  })();
59
- for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
83
+ exports.EFFECT_BFF_CONTEXT_STORAGE_SHARE = __webpack_exports__.EFFECT_BFF_CONTEXT_STORAGE_SHARE;
84
+ exports.EFFECT_BFF_HANDLER_FACTORY_REGISTRY_SHARE = __webpack_exports__.EFFECT_BFF_HANDLER_FACTORY_REGISTRY_SHARE;
85
+ exports.adoptEffectBffShareScope = __webpack_exports__.adoptEffectBffShareScope;
86
+ exports.createEffectBffEdgeDispatcherFactory = __webpack_exports__.createEffectBffEdgeDispatcherFactory;
87
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
88
+ "EFFECT_BFF_CONTEXT_STORAGE_SHARE",
89
+ "EFFECT_BFF_HANDLER_FACTORY_REGISTRY_SHARE",
90
+ "adoptEffectBffShareScope",
91
+ "createEffectBffEdgeDispatcherFactory"
92
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
60
93
  Object.defineProperty(exports, '__esModule', {
61
94
  value: true
62
95
  });
@@ -35,11 +35,10 @@ __webpack_require__.d(__webpack_exports__, {
35
35
  normalizeEffectPrefix: ()=>normalizeEffectPrefix,
36
36
  toOperationContractSources: ()=>toOperationContractSources
37
37
  });
38
- const bff_core_namespaceObject = require("@modern-js/bff-core");
38
+ const node_namespaceObject = require("@modern-js/server-runtime-extensions/bff-policy/node");
39
39
  const external_entry_shape_js_namespaceObject = require("./entry-shape.js");
40
40
  function resolveEffectEndpointName(endpoint) {
41
41
  if ('string' == typeof endpoint.identifier && endpoint.identifier) return endpoint.identifier;
42
- if ('string' == typeof endpoint.name && endpoint.name) return endpoint.name;
43
42
  return '';
44
43
  }
45
44
  function ensureLeadingSlash(pathname) {
@@ -97,10 +96,10 @@ async function extractHttpApiFromModule(mod, isHttpApi) {
97
96
  isValidatorAwareHandlerFactory: external_entry_shape_js_namespaceObject.isValidatorAwareHandlerFactory,
98
97
  isHttpApi
99
98
  });
100
- return !facts?.legacyShape && facts?.api !== void 0 && facts.hasRuntimeLayer && (void 0 === facts.createHandler || facts.createHandlerValidatorAware) ? facts.api : null;
99
+ return !facts?.unsupportedShape && facts?.api !== void 0 && facts.hasRuntimeLayer && (void 0 === facts.createHandler || facts.createHandlerValidatorAware) ? facts.api : null;
101
100
  }
102
101
  function createEffectEndpointContractHash(endpoint, requestId) {
103
- return (0, bff_core_namespaceObject.createOperationContractHash)(createEffectOperationContractSource(endpoint), requestId);
102
+ return (0, node_namespaceObject.createOperationContractHash)(createEffectOperationContractSource(endpoint), requestId);
104
103
  }
105
104
  exports.collectEffectEndpoints = __webpack_exports__.collectEffectEndpoints;
106
105
  exports.createEffectEndpointContractHash = __webpack_exports__.createEffectEndpointContractHash;