@bleedingdev/modern-js-bff-effect 3.9.0-ultramodern.1 → 3.9.0-ultramodern.10

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 (115) hide show
  1. package/README.md +20 -4
  2. package/dist/cjs/{effect-client/guards.js → assembly.js} +15 -9
  3. package/dist/cjs/data-platform/trace.js +2 -2
  4. package/dist/cjs/effect/edge-dispatcher.js +7 -7
  5. package/dist/cjs/effect/edge.js +15 -2
  6. package/dist/cjs/effect/endpoint-contracts.js +3 -4
  7. package/dist/cjs/effect/entry-shape.js +2 -2
  8. package/dist/cjs/effect/generated-entry.js +57 -0
  9. package/dist/cjs/effect/handler/batch-handler.js +5 -4
  10. package/dist/cjs/effect/handler/batch.js +8 -1
  11. package/dist/cjs/effect/handler/definition.js +1 -21
  12. package/dist/cjs/effect/module.js +4 -4
  13. package/dist/cjs/effect/operation-context.js +7 -7
  14. package/dist/cjs/effect-client/cross-project.js +92 -0
  15. package/dist/cjs/effect-client/index.js +5 -3
  16. package/dist/cjs/microvertical-api.js +120 -0
  17. package/dist/esm/assembly.mjs +12 -0
  18. package/dist/esm/data-platform/trace.mjs +1 -1
  19. package/dist/esm/effect/edge-dispatcher.mjs +5 -5
  20. package/dist/esm/effect/edge.mjs +1 -0
  21. package/dist/esm/effect/endpoint-contracts.mjs +2 -3
  22. package/dist/esm/effect/entry-shape.mjs +2 -2
  23. package/dist/esm/effect/generated-entry.mjs +19 -0
  24. package/dist/esm/effect/handler/batch-handler.mjs +5 -4
  25. package/dist/esm/effect/handler/batch.mjs +8 -1
  26. package/dist/esm/effect/handler/definition.mjs +1 -21
  27. package/dist/esm/effect/module.mjs +4 -4
  28. package/dist/esm/effect/operation-context.mjs +1 -1
  29. package/dist/esm/effect-client/cross-project.mjs +54 -0
  30. package/dist/esm/effect-client/index.mjs +4 -2
  31. package/dist/esm/microvertical-api.mjs +67 -0
  32. package/dist/esm-node/assembly.mjs +13 -0
  33. package/dist/esm-node/data-platform/trace.mjs +1 -1
  34. package/dist/esm-node/effect/edge-dispatcher.mjs +5 -5
  35. package/dist/esm-node/effect/edge.mjs +1 -0
  36. package/dist/esm-node/effect/endpoint-contracts.mjs +2 -3
  37. package/dist/esm-node/effect/entry-shape.mjs +2 -2
  38. package/dist/esm-node/effect/generated-entry.mjs +20 -0
  39. package/dist/esm-node/effect/handler/batch-handler.mjs +5 -4
  40. package/dist/esm-node/effect/handler/batch.mjs +8 -1
  41. package/dist/esm-node/effect/handler/definition.mjs +1 -21
  42. package/dist/esm-node/effect/module.mjs +4 -4
  43. package/dist/esm-node/effect/operation-context.mjs +1 -1
  44. package/dist/esm-node/effect-client/cross-project.mjs +55 -0
  45. package/dist/esm-node/effect-client/index.mjs +4 -2
  46. package/dist/esm-node/microvertical-api.mjs +68 -0
  47. package/dist/types/assembly.d.ts +10 -0
  48. package/dist/types/effect/context.d.ts +1 -1
  49. package/dist/types/effect/edge-context.d.ts +1 -1
  50. package/dist/types/effect/edge-dispatcher.d.ts +2 -2
  51. package/dist/types/effect/edge.d.ts +1 -0
  52. package/dist/types/effect/endpoint-contracts.d.ts +2 -20
  53. package/dist/types/effect/entry-shape.d.ts +2 -2
  54. package/dist/types/effect/generated-entry.d.ts +7 -0
  55. package/dist/types/effect/handler/batch.d.ts +7 -1
  56. package/dist/types/effect/handler/types.d.ts +0 -15
  57. package/dist/types/effect/handler.d.ts +1 -1
  58. package/dist/types/effect/operation-context.d.ts +1 -1
  59. package/dist/types/effect-client/cross-project.d.ts +10 -0
  60. package/dist/types/effect-client/index.d.ts +4 -1
  61. package/dist/types/microvertical-api.d.ts +65 -0
  62. package/package.json +34 -21
  63. package/src/assembly.ts +43 -0
  64. package/src/data-platform/batch/queue.ts +2 -3
  65. package/src/data-platform/trace.ts +1 -1
  66. package/src/effect/edge-dispatcher.ts +7 -5
  67. package/src/effect/edge.ts +1 -0
  68. package/src/effect/endpoint-contracts.ts +3 -24
  69. package/src/effect/entry-shape.ts +10 -5
  70. package/src/effect/generated-entry.ts +36 -0
  71. package/src/effect/handler/batch-handler.ts +21 -16
  72. package/src/effect/handler/batch.ts +9 -1
  73. package/src/effect/handler/definition.ts +0 -44
  74. package/src/effect/handler/http.ts +2 -2
  75. package/src/effect/handler/types.ts +0 -27
  76. package/src/effect/handler.ts +0 -1
  77. package/src/effect/module.ts +4 -4
  78. package/src/effect/operation-context.ts +1 -1
  79. package/src/effect-client/cross-project.ts +109 -0
  80. package/src/effect-client/index.ts +13 -3
  81. package/src/microvertical-api.ts +102 -0
  82. package/dist/cjs/effect-client/batch.js +0 -73
  83. package/dist/cjs/effect-client/envelope.js +0 -145
  84. package/dist/cjs/effect-client/request-context.js +0 -64
  85. package/dist/cjs/effect-client/request.js +0 -66
  86. package/dist/cjs/effect-client/runtime.js +0 -100
  87. package/dist/cjs/effect-client/types.js +0 -18
  88. package/dist/esm/effect-client/batch.mjs +0 -35
  89. package/dist/esm/effect-client/envelope.mjs +0 -104
  90. package/dist/esm/effect-client/guards.mjs +0 -3
  91. package/dist/esm/effect-client/request-context.mjs +0 -23
  92. package/dist/esm/effect-client/request.mjs +0 -28
  93. package/dist/esm/effect-client/runtime.mjs +0 -62
  94. package/dist/esm/effect-client/types.mjs +0 -0
  95. package/dist/esm-node/effect-client/batch.mjs +0 -36
  96. package/dist/esm-node/effect-client/envelope.mjs +0 -105
  97. package/dist/esm-node/effect-client/guards.mjs +0 -4
  98. package/dist/esm-node/effect-client/request-context.mjs +0 -24
  99. package/dist/esm-node/effect-client/request.mjs +0 -29
  100. package/dist/esm-node/effect-client/runtime.mjs +0 -63
  101. package/dist/esm-node/effect-client/types.mjs +0 -1
  102. package/dist/types/effect-client/batch.d.ts +0 -2
  103. package/dist/types/effect-client/envelope.d.ts +0 -15
  104. package/dist/types/effect-client/guards.d.ts +0 -2
  105. package/dist/types/effect-client/request-context.d.ts +0 -3
  106. package/dist/types/effect-client/request.d.ts +0 -1
  107. package/dist/types/effect-client/runtime.d.ts +0 -5
  108. package/dist/types/effect-client/types.d.ts +0 -68
  109. package/src/effect-client/batch.ts +0 -50
  110. package/src/effect-client/envelope.ts +0 -238
  111. package/src/effect-client/guards.ts +0 -6
  112. package/src/effect-client/request-context.ts +0 -54
  113. package/src/effect-client/request.ts +0 -51
  114. package/src/effect-client/runtime.ts +0 -122
  115. 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.
@@ -27,17 +27,23 @@ 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
+ __webpack_require__.d(__webpack_exports__, {
31
+ assembleEffectBffRuntime: ()=>assembleEffectBffRuntime
35
32
  });
36
- exports.isRecord = __webpack_exports__.isRecord;
37
- exports.stringOrUndefined = __webpack_exports__.stringOrUndefined;
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;
38
45
  for(var __rspack_i in __webpack_exports__)if (-1 === [
39
- "isRecord",
40
- "stringOrUndefined"
46
+ "assembleEffectBffRuntime"
41
47
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
42
48
  Object.defineProperty(exports, '__esModule', {
43
49
  value: true
@@ -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();
@@ -97,13 +97,13 @@ __webpack_require__.d(__webpack_exports__, {
97
97
  useEffectContext: ()=>external_edge_context_js_namespaceObject.useEffectContext,
98
98
  useOperationContext: ()=>external_edge_context_js_namespaceObject.useOperationContext
99
99
  });
100
- const cross_project_policy_namespaceObject = require("@modern-js/bff-core/security/cross-project-policy");
100
+ const bff_policy_namespaceObject = require("@modern-js/server-runtime-extensions/bff-policy");
101
+ const Effect_namespaceObject = require("effect/Effect");
101
102
  const external_headers_js_namespaceObject = require("../headers.js");
102
103
  const external_dispatch_js_namespaceObject = require("./dispatch.js");
103
104
  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");
@@ -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,9 @@
2
2
  var __webpack_modules__ = {
3
3
  "./edge-dispatcher" (module) {
4
4
  module.exports = require("./edge-dispatcher.js");
5
+ },
6
+ "./generated-entry" (module) {
7
+ module.exports = require("./generated-entry.js");
5
8
  }
6
9
  };
7
10
  var __webpack_module_cache__ = {};
@@ -53,10 +56,20 @@ var __webpack_exports__ = {};
53
56
  __webpack_require__.r(__webpack_exports__);
54
57
  var _edge_dispatcher__rspack_import_0 = __webpack_require__("./edge-dispatcher");
55
58
  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];
59
+ for(const __rspack_import_key in _edge_dispatcher__rspack_import_0)if ([
60
+ "createEffectBffEdgeDispatcherFactory",
61
+ "default"
62
+ ].indexOf(__rspack_import_key) < 0) __rspack_reexport[__rspack_import_key] = ()=>_edge_dispatcher__rspack_import_0[__rspack_import_key];
57
63
  __webpack_require__.d(__webpack_exports__, __rspack_reexport);
64
+ var _generated_entry__rspack_import_1 = __webpack_require__("./generated-entry");
65
+ __webpack_require__.d(__webpack_exports__, {
66
+ createEffectBffEdgeDispatcherFactory: ()=>_generated_entry__rspack_import_1.createEffectBffEdgeDispatcherFactory
67
+ });
58
68
  })();
59
- for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
69
+ exports.createEffectBffEdgeDispatcherFactory = __webpack_exports__.createEffectBffEdgeDispatcherFactory;
70
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
71
+ "createEffectBffEdgeDispatcherFactory"
72
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
60
73
  Object.defineProperty(exports, '__esModule', {
61
74
  value: true
62
75
  });
@@ -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;
@@ -77,13 +77,13 @@ function classifyEffectBffEntryModule(value, predicates) {
77
77
  if (predicates.isRequestHandler(module.handler)) return createEntryShapeFacts(module, predicates, '`handler` export');
78
78
  return createEntryShapeFacts(module, predicates);
79
79
  }
80
- function createEntryShapeFacts(module, predicates, legacyShape) {
80
+ function createEntryShapeFacts(module, predicates, unsupportedShape) {
81
81
  const createHandler = 'function' == typeof module.createHandler ? module.createHandler : void 0;
82
82
  const api = predicates.isHttpApi(module.api) ? module.api : void 0;
83
83
  const hasRuntimeLayer = void 0 !== module.layer;
84
84
  return {
85
85
  module,
86
- legacyShape,
86
+ unsupportedShape,
87
87
  createHandler,
88
88
  createHandlerValidatorAware: void 0 !== createHandler && predicates.isValidatorAwareHandlerFactory(createHandler),
89
89
  api,
@@ -0,0 +1,57 @@
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
+ createEffectBffEdgeDispatcherFactory: ()=>createEffectBffEdgeDispatcherFactory
32
+ });
33
+ const external_edge_dispatcher_js_namespaceObject = require("./edge-dispatcher.js");
34
+ function createEffectBffEdgeDispatcherFactory(module, generatedOperationContracts) {
35
+ return (options)=>{
36
+ const policy = options?.crossProjectPolicy;
37
+ const crossProjectPolicy = null == policy || null === policy.expectedOperationContracts || 'object' != typeof policy.expectedOperationContracts || Array.isArray(policy.expectedOperationContracts) ? policy : {
38
+ ...policy,
39
+ expectedOperationContracts: {
40
+ ...policy.expectedOperationContracts,
41
+ ...generatedOperationContracts
42
+ }
43
+ };
44
+ return (0, external_edge_dispatcher_js_namespaceObject.createEffectBffEdgeDispatcher)({
45
+ ...options,
46
+ crossProjectPolicy,
47
+ module
48
+ });
49
+ };
50
+ }
51
+ exports.createEffectBffEdgeDispatcherFactory = __webpack_exports__.createEffectBffEdgeDispatcherFactory;
52
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
53
+ "createEffectBffEdgeDispatcherFactory"
54
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
55
+ Object.defineProperty(exports, '__esModule', {
56
+ value: true
57
+ });
@@ -30,6 +30,7 @@ __webpack_require__.r(__webpack_exports__);
30
30
  __webpack_require__.d(__webpack_exports__, {
31
31
  createDataPlatformBatchRequestHandler: ()=>createDataPlatformBatchRequestHandler
32
32
  });
33
+ const Effect_namespaceObject = require("effect/Effect");
33
34
  const index_js_namespaceObject = require("../../data-platform/index.js");
34
35
  const protocol_js_namespaceObject = require("../../data-platform/batch/protocol.js");
35
36
  const external_batch_js_namespaceObject = require("./batch.js");
@@ -216,25 +217,25 @@ function createDataPlatformBatchRequestHandler(options) {
216
217
  return (0, protocol_js_namespaceObject.toBatchResponseItem)(itemId, itemResponse, 'HEAD' === itemMethod);
217
218
  } catch (error) {
218
219
  if (error instanceof external_batch_js_namespaceObject.BatchItemTimeoutError) {
219
- console.error({
220
+ Effect_namespaceObject.runSync(Effect_namespaceObject.logError({
220
221
  event: 'bff.batch.item.timeout',
221
222
  batchId: payload.batchId,
222
223
  itemId,
223
224
  method: itemMethod,
224
225
  path: itemPathname,
225
226
  errorName: error.name
226
- });
227
+ }));
227
228
  return (0, external_batch_js_namespaceObject.toBatchItemError)(itemId, 504, 'Batch item request timed out');
228
229
  }
229
230
  if (error instanceof Response) return (0, protocol_js_namespaceObject.toBatchResponseItem)(itemId, error, 'HEAD' === itemMethod);
230
- console.error({
231
+ Effect_namespaceObject.runSync(Effect_namespaceObject.logError({
231
232
  event: 'bff.batch.item.failure',
232
233
  batchId: payload.batchId,
233
234
  itemId,
234
235
  method: itemMethod,
235
236
  path: itemPathname,
236
237
  errorName: error instanceof Error ? error.name : 'UnknownError'
237
- });
238
+ }));
238
239
  return (0, external_batch_js_namespaceObject.toBatchItemError)(itemId, 500, 'Internal Server Error');
239
240
  } finally{
240
241
  request.signal.removeEventListener('abort', abortFromBatchRequest);
@@ -39,6 +39,7 @@ __webpack_require__.d(__webpack_exports__, {
39
39
  toBatchItemError: ()=>toBatchItemError,
40
40
  toHeaderRecord: ()=>external_headers_js_namespaceObject.toHeaderRecord
41
41
  });
42
+ const Data_namespaceObject = require("effect/Data");
42
43
  const index_js_namespaceObject = require("../../data-platform/index.js");
43
44
  const protocol_js_namespaceObject = require("../../data-platform/batch/protocol.js");
44
45
  const external_headers_js_namespaceObject = require("../../headers.js");
@@ -106,7 +107,13 @@ function toBatchItemError(id, status, message) {
106
107
  }))
107
108
  };
108
109
  }
109
- class BatchItemTimeoutError extends Error {
110
+ class BatchItemTimeoutError extends Data_namespaceObject.TaggedError('BatchItemTimeoutError') {
111
+ constructor(message){
112
+ super({
113
+ message
114
+ });
115
+ this.name = 'Error';
116
+ }
110
117
  }
111
118
  function promiseWithTimeout(effect, timeoutMs, onTimeout) {
112
119
  if (timeoutMs <= 0) return effect;
@@ -53,30 +53,10 @@ function defineEffectBff(definition) {
53
53
  validateRequest: options?.validateRequest
54
54
  });
55
55
  });
56
- const client = createLoaderMaterializedClientPlaceholder();
57
56
  return {
58
57
  ...definition,
59
- createHandler,
60
- client
61
- };
62
- }
63
- const LOADER_CLIENT_IGNORED_KEYS = new Set([
64
- 'then',
65
- 'catch',
66
- 'finally',
67
- 'toJSON',
68
- '$$typeof'
69
- ]);
70
- function createLoaderMaterializedClientPlaceholder() {
71
- const explain = (property)=>{
72
- throw new Error(`[BFF][Effect] client.${String(property)} is not available here: the typed client only exists when the API entry is imported through the "@api/index" transformed path (the BFF loader replaces it with generated client code). On the server, use HttpApiClient or call the Effect layer directly.`);
58
+ createHandler
73
59
  };
74
- return new Proxy(Object.create(null), {
75
- get (_target, property) {
76
- if ('symbol' == typeof property || LOADER_CLIENT_IGNORED_KEYS.has(property)) return;
77
- return explain(property);
78
- }
79
- });
80
60
  }
81
61
  function defineEffectRpcBff(definition) {
82
62
  const createHandler = (options)=>(0, external_rpc_js_namespaceObject.createRpcApiHandler)({
@@ -43,7 +43,7 @@ function shareDispose(dispose) {
43
43
  return disposePromise;
44
44
  };
45
45
  }
46
- function rejectLegacyEffectModuleShape(options, shape) {
46
+ function rejectUnsupportedEffectModuleShape(options, shape) {
47
47
  options.onWarning?.(`${external_entry_shape_js_namespaceObject.strictEffectApproachMessage} Rejected ${shape}.`);
48
48
  return true;
49
49
  }
@@ -71,8 +71,8 @@ function classifyEffectBffRuntimeEntryShape(module) {
71
71
  }
72
72
  function resolveClassifiedEffectBffModuleHandler(facts, options = {}) {
73
73
  if (!facts) return null;
74
- if (facts.legacyShape) {
75
- if (rejectLegacyEffectModuleShape(options, facts.legacyShape)) return null;
74
+ if (facts.unsupportedShape) {
75
+ if (rejectUnsupportedEffectModuleShape(options, facts.unsupportedShape)) return null;
76
76
  }
77
77
  if ('function' == typeof facts.createHandler) {
78
78
  if (facts.createHandlerValidatorAware) {
@@ -85,7 +85,7 @@ function resolveClassifiedEffectBffModuleHandler(facts, options = {}) {
85
85
  return createLoadedHandler(webHandler);
86
86
  }
87
87
  if (void 0 === facts.api || !facts.hasRuntimeLayer) {
88
- rejectLegacyEffectModuleShape(options, 'unbranded `createHandler` export');
88
+ rejectUnsupportedEffectModuleShape(options, 'unbranded `createHandler` export');
89
89
  return null;
90
90
  }
91
91
  options.onWarning?.(`${external_entry_shape_js_namespaceObject.strictEffectApproachMessage} Ignored unbranded \`createHandler\` export and rebuilt the handler from its { api, layer } exports.`);
@@ -31,7 +31,7 @@ __webpack_require__.d(__webpack_exports__, {
31
31
  createEffectOperationContext: ()=>createEffectOperationContext,
32
32
  kEffectContextStorage: ()=>kEffectContextStorage
33
33
  });
34
- const create_request_namespaceObject = require("@modern-js/create-request");
34
+ const request_context_namespaceObject = require("@modern-js/runtime-extensions/request-context");
35
35
  const kEffectContextStorage = Symbol.for('modernjs.plugin-bff.effectContextStorage');
36
36
  const readHeader = (headers, header)=>{
37
37
  const value = headers.get(header);
@@ -42,7 +42,7 @@ const copyStringField = (target, details, key)=>{
42
42
  if ('string' == typeof value && value.length > 0) target[key] = value;
43
43
  };
44
44
  const readOperationContextDetails = (request)=>{
45
- const rawDetails = readHeader(request.headers, create_request_namespaceObject.BFF_OPERATION_CONTEXT_DETAIL_HEADER);
45
+ const rawDetails = readHeader(request.headers, request_context_namespaceObject.BFF_OPERATION_CONTEXT_DETAIL_HEADER);
46
46
  if (!rawDetails) return {};
47
47
  try {
48
48
  const parsed = JSON.parse(rawDetails);
@@ -70,16 +70,16 @@ const createEffectOperationContext = ({ request, path, method })=>{
70
70
  delete operationDetails.traceId;
71
71
  delete operationDetails.spanId;
72
72
  const servicePath = new URL(request.url).pathname;
73
- const headerTraceparent = readHeader(request.headers, create_request_namespaceObject.BFF_TRACEPARENT_HEADER);
74
- const headerTraceContext = (0, create_request_namespaceObject.parseTraceparent)(headerTraceparent);
75
- const detailTraceContext = (0, create_request_namespaceObject.parseTraceparent)(details.traceparent);
73
+ const headerTraceparent = readHeader(request.headers, request_context_namespaceObject.BFF_TRACEPARENT_HEADER);
74
+ const headerTraceContext = (0, request_context_namespaceObject.parseTraceparent)(headerTraceparent);
75
+ const detailTraceContext = (0, request_context_namespaceObject.parseTraceparent)(details.traceparent);
76
76
  const traceparent = headerTraceContext ? headerTraceparent : detailTraceContext ? details.traceparent : void 0;
77
77
  const parsedTraceparent = headerTraceContext || detailTraceContext || (details.traceId && details.spanId ? {
78
78
  traceId: details.traceId,
79
79
  spanId: details.spanId
80
80
  } : void 0);
81
- const locale = readHeader(request.headers, create_request_namespaceObject.BFF_LOCALE_HEADER);
82
- const headerOperationId = readHeader(request.headers, create_request_namespaceObject.BFF_OPERATION_CONTEXT_HEADER);
81
+ const locale = readHeader(request.headers, request_context_namespaceObject.BFF_LOCALE_HEADER);
82
+ const headerOperationId = readHeader(request.headers, request_context_namespaceObject.BFF_OPERATION_CONTEXT_HEADER);
83
83
  return {
84
84
  ...operationDetails,
85
85
  ...headerOperationId || details.operationId ? {
@@ -0,0 +1,92 @@
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
+ withCrossProjectPolicy: ()=>withCrossProjectPolicy
32
+ });
33
+ const bff_policy_namespaceObject = require("@modern-js/server-runtime-extensions/bff-policy");
34
+ const Effect_namespaceObject = require("effect/Effect");
35
+ const Schema_namespaceObject = require("effect/Schema");
36
+ const http_namespaceObject = require("effect/unstable/http");
37
+ const httpapi_namespaceObject = require("effect/unstable/httpapi");
38
+ const encodeJson = Schema_namespaceObject.encodeSync(Schema_namespaceObject.fromJsonString(Schema_namespaceObject.Unknown));
39
+ function withCrossProjectPolicy(api, options, client) {
40
+ const contracts = {};
41
+ const prefix = options.prefix.replace(/\/$/, '');
42
+ httpapi_namespaceObject.HttpApi.reflect(api, {
43
+ onGroup: ()=>{},
44
+ onEndpoint: ({ endpoint })=>{
45
+ const routePath = `${prefix}${'/' === endpoint.path ? '' : endpoint.path}` || '/';
46
+ const name = endpoint.identifier;
47
+ contracts[`${endpoint.method}:${routePath}`] = {
48
+ operationId: `${options.requestId}:${name}`,
49
+ name,
50
+ method: endpoint.method,
51
+ routePath
52
+ };
53
+ }
54
+ });
55
+ return client.pipe(http_namespaceObject.HttpClient.mapRequestEffect((request)=>{
56
+ const observed = (0, bff_policy_namespaceObject.resolveCrossProjectRequestObservation)({
57
+ method: request.method,
58
+ pathname: new URL(request.url, 'http://effect.invalid').pathname
59
+ }, {
60
+ expectedOperationContracts: contracts
61
+ });
62
+ const contract = observed && contracts[`${observed.method}:${observed.routePath}`];
63
+ if (void 0 === contract) return Effect_namespaceObject.die(new Error('[BFF][Effect] Request has no matching shared operation contract.'));
64
+ return Effect_namespaceObject.gen(function*() {
65
+ const input = encodeJson({
66
+ httpMethod: contract.method,
67
+ name: contract.name,
68
+ requestId: options.requestId,
69
+ routePath: contract.routePath
70
+ });
71
+ const digest = yield* Effect_namespaceObject.promise(()=>globalThis.crypto.subtle.digest('SHA-256', new TextEncoder().encode(input)));
72
+ const schemaHash = Array.from(new Uint8Array(digest), (value)=>value.toString(16).padStart(2, '0')).join('');
73
+ return request.pipe(http_namespaceObject.HttpClientRequest.setHeader(bff_policy_namespaceObject.BFF_ENVELOPE_HEADER, encodeJson({
74
+ requestId: options.requestId
75
+ })), http_namespaceObject.HttpClientRequest.setHeader(bff_policy_namespaceObject.BFF_OPERATION_CONTEXT_HEADER, contract.operationId), http_namespaceObject.HttpClientRequest.setHeader(bff_policy_namespaceObject.BFF_OPERATION_CONTEXT_DETAIL_HEADER, encodeJson({
76
+ requestId: options.requestId,
77
+ operationId: contract.operationId,
78
+ method: contract.method,
79
+ routePath: contract.routePath,
80
+ schemaHash,
81
+ operationVersion: options.operationVersion
82
+ })));
83
+ });
84
+ }));
85
+ }
86
+ exports.withCrossProjectPolicy = __webpack_exports__.withCrossProjectPolicy;
87
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
88
+ "withCrossProjectPolicy"
89
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
90
+ Object.defineProperty(exports, '__esModule', {
91
+ value: true
92
+ });
@@ -50,7 +50,7 @@ __webpack_require__.d(__webpack_exports__, {
50
50
  runEffectView: ()=>runEffectView,
51
51
  view: ()=>view
52
52
  });
53
- const create_request_namespaceObject = require("@modern-js/create-request");
53
+ const request_context_namespaceObject = require("@modern-js/runtime-extensions/request-context");
54
54
  const Data_namespaceObject = require("effect/Data");
55
55
  const Effect_namespaceObject = require("effect/Effect");
56
56
  const Exit_namespaceObject = require("effect/Exit");
@@ -61,6 +61,7 @@ const http_namespaceObject = require("effect/unstable/http");
61
61
  const httpapi_namespaceObject = require("effect/unstable/httpapi");
62
62
  const rpc_namespaceObject = require("effect/unstable/rpc");
63
63
  const rpcSerialization_js_namespaceObject = require("../effect/rpcSerialization.js");
64
+ const external_cross_project_js_namespaceObject = require("./cross-project.js");
64
65
  const Schema_namespaceObject = require("effect/Schema");
65
66
  const HttpClientError_namespaceObject = require("effect/unstable/http/HttpClientError");
66
67
  class EffectRpcClientError extends Data_namespaceObject.TaggedError('EffectRpcClientError') {
@@ -91,14 +92,15 @@ function runEffectView(request, selection) {
91
92
  });
92
93
  }
93
94
  function makeEffectHttpApiClient(api, options) {
94
- const requestContextHeaders = (0, create_request_namespaceObject.createRequestContextHeaders)(options?.requestContext);
95
+ const requestContextHeaders = (0, request_context_namespaceObject.createRequestContextHeaders)(options?.requestContext);
95
96
  const transformClient = (client)=>{
96
97
  const contextClient = 0 === Object.keys(requestContextHeaders).length ? client : client.pipe(http_namespaceObject.HttpClient.mapRequest((request)=>{
97
98
  let nextRequest = request;
98
99
  for (const [header, value] of Object.entries(requestContextHeaders))if (void 0 === nextRequest.headers[header.toLowerCase()]) nextRequest = http_namespaceObject.HttpClientRequest.setHeader(nextRequest, header, value);
99
100
  return nextRequest;
100
101
  }));
101
- return 'function' == typeof options?.transformClient ? options.transformClient(contextClient) : contextClient;
102
+ const policyClient = options?.crossProject !== void 0 ? (0, external_cross_project_js_namespaceObject.withCrossProjectPolicy)(api, options.crossProject, contextClient) : contextClient;
103
+ return 'function' == typeof options?.transformClient ? options.transformClient(policyClient) : policyClient;
102
104
  };
103
105
  return httpapi_namespaceObject.HttpApiClient.make(api, {
104
106
  baseUrl: options?.baseUrl,