@bleedingdev/modern-js-bff-effect 3.8.3-ultramodern.6 → 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 (142) 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-registry.mjs +1 -1
  23. package/dist/esm/effect/entry-shape.mjs +2 -2
  24. package/dist/esm/effect/generated-entry.mjs +19 -0
  25. package/dist/esm/effect/handler/batch-handler.mjs +5 -4
  26. package/dist/esm/effect/handler/batch.mjs +8 -1
  27. package/dist/esm/effect/handler/definition.mjs +1 -21
  28. package/dist/esm/effect/module.mjs +4 -4
  29. package/dist/esm/effect/operation-context.mjs +1 -1
  30. package/dist/esm/effect-client/cross-project.mjs +54 -0
  31. package/dist/esm/effect-client/index.mjs +4 -2
  32. package/dist/esm/microvertical-api.mjs +67 -0
  33. package/dist/esm-node/assembly.mjs +13 -0
  34. package/dist/esm-node/data-platform/trace.mjs +1 -1
  35. package/dist/esm-node/effect/edge-dispatcher.mjs +5 -5
  36. package/dist/esm-node/effect/edge.mjs +1 -0
  37. package/dist/esm-node/effect/endpoint-contracts.mjs +2 -3
  38. package/dist/esm-node/effect/entry-shape-registry.mjs +1 -1
  39. package/dist/esm-node/effect/entry-shape.mjs +2 -2
  40. package/dist/esm-node/effect/generated-entry.mjs +20 -0
  41. package/dist/esm-node/effect/handler/batch-handler.mjs +5 -4
  42. package/dist/esm-node/effect/handler/batch.mjs +8 -1
  43. package/dist/esm-node/effect/handler/definition.mjs +1 -21
  44. package/dist/esm-node/effect/module.mjs +4 -4
  45. package/dist/esm-node/effect/operation-context.mjs +1 -1
  46. package/dist/esm-node/effect-client/cross-project.mjs +55 -0
  47. package/dist/esm-node/effect-client/index.mjs +4 -2
  48. package/dist/esm-node/microvertical-api.mjs +68 -0
  49. package/dist/types/assembly.d.ts +10 -0
  50. package/dist/types/data-platform/batch/protocol.d.ts +1 -1
  51. package/dist/types/data-platform/batch/queue.d.ts +1 -1
  52. package/dist/types/data-platform/batch/request.d.ts +1 -1
  53. package/dist/types/data-platform/batch/response.d.ts +1 -1
  54. package/dist/types/data-platform/batch/telemetry.d.ts +1 -1
  55. package/dist/types/data-platform/batch/url.d.ts +1 -1
  56. package/dist/types/data-platform/batch-transport.d.ts +3 -3
  57. package/dist/types/data-platform/codec.d.ts +1 -1
  58. package/dist/types/data-platform/index.d.ts +8 -8
  59. package/dist/types/data-platform/invalidation.d.ts +1 -1
  60. package/dist/types/data-platform/trace.d.ts +1 -1
  61. package/dist/types/data-platform/validation.d.ts +1 -1
  62. package/dist/types/effect/context.d.ts +3 -3
  63. package/dist/types/effect/dispatch.d.ts +2 -2
  64. package/dist/types/effect/edge-context.d.ts +3 -3
  65. package/dist/types/effect/edge-dispatcher.d.ts +9 -9
  66. package/dist/types/effect/edge.d.ts +2 -1
  67. package/dist/types/effect/endpoint-contracts.d.ts +2 -20
  68. package/dist/types/effect/entry-shape.d.ts +2 -2
  69. package/dist/types/effect/generated-entry.d.ts +7 -0
  70. package/dist/types/effect/handler/batch-handler.d.ts +1 -1
  71. package/dist/types/effect/handler/batch.d.ts +9 -3
  72. package/dist/types/effect/handler/definition.d.ts +1 -1
  73. package/dist/types/effect/handler/envelope.d.ts +1 -1
  74. package/dist/types/effect/handler/http.d.ts +1 -1
  75. package/dist/types/effect/handler/openapi.d.ts +1 -1
  76. package/dist/types/effect/handler/rpc.d.ts +1 -1
  77. package/dist/types/effect/handler/types.d.ts +2 -17
  78. package/dist/types/effect/handler.d.ts +3 -3
  79. package/dist/types/effect/index.d.ts +5 -5
  80. package/dist/types/effect/module.d.ts +2 -2
  81. package/dist/types/effect/operation-context.d.ts +1 -1
  82. package/dist/types/effect/rpcSerialization.d.ts +1 -1
  83. package/dist/types/effect-client/cross-project.d.ts +10 -0
  84. package/dist/types/effect-client/index.d.ts +4 -1
  85. package/dist/types/index.d.ts +3 -3
  86. package/dist/types/microvertical-api.d.ts +65 -0
  87. package/package.json +35 -22
  88. package/src/assembly.ts +43 -0
  89. package/src/data-platform/batch/queue.ts +2 -3
  90. package/src/data-platform/trace.ts +1 -1
  91. package/src/effect/edge-dispatcher.ts +7 -5
  92. package/src/effect/edge.ts +1 -0
  93. package/src/effect/endpoint-contracts.ts +3 -24
  94. package/src/effect/entry-shape.ts +10 -5
  95. package/src/effect/generated-entry.ts +36 -0
  96. package/src/effect/handler/batch-handler.ts +21 -16
  97. package/src/effect/handler/batch.ts +9 -1
  98. package/src/effect/handler/definition.ts +0 -44
  99. package/src/effect/handler/http.ts +2 -2
  100. package/src/effect/handler/types.ts +0 -27
  101. package/src/effect/handler.ts +0 -1
  102. package/src/effect/module.ts +4 -4
  103. package/src/effect/operation-context.ts +1 -1
  104. package/src/effect-client/cross-project.ts +109 -0
  105. package/src/effect-client/index.ts +13 -3
  106. package/src/microvertical-api.ts +102 -0
  107. package/dist/cjs/effect-client/batch.js +0 -73
  108. package/dist/cjs/effect-client/envelope.js +0 -145
  109. package/dist/cjs/effect-client/request-context.js +0 -64
  110. package/dist/cjs/effect-client/request.js +0 -66
  111. package/dist/cjs/effect-client/runtime.js +0 -100
  112. package/dist/cjs/effect-client/types.js +0 -18
  113. package/dist/esm/effect-client/batch.mjs +0 -35
  114. package/dist/esm/effect-client/envelope.mjs +0 -104
  115. package/dist/esm/effect-client/guards.mjs +0 -3
  116. package/dist/esm/effect-client/request-context.mjs +0 -23
  117. package/dist/esm/effect-client/request.mjs +0 -28
  118. package/dist/esm/effect-client/runtime.mjs +0 -62
  119. package/dist/esm/effect-client/types.mjs +0 -0
  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-client/batch.d.ts +0 -2
  128. package/dist/types/effect-client/envelope.d.ts +0 -15
  129. package/dist/types/effect-client/guards.d.ts +0 -2
  130. package/dist/types/effect-client/request-context.d.ts +0 -3
  131. package/dist/types/effect-client/request.d.ts +0 -1
  132. package/dist/types/effect-client/runtime.d.ts +0 -5
  133. package/dist/types/effect-client/types.d.ts +0 -68
  134. package/src/effect-client/batch.ts +0 -50
  135. package/src/effect-client/envelope.ts +0 -238
  136. package/src/effect-client/guards.ts +0 -6
  137. package/src/effect-client/request-context.ts +0 -54
  138. package/src/effect-client/request.ts +0 -51
  139. package/src/effect-client/runtime.ts +0 -122
  140. package/src/effect-client/types.ts +0 -84
  141. /package/dist/esm/{rslib-runtime.mjs → rslib-runtime~1.mjs} +0 -0
  142. /package/dist/esm-node/{rslib-runtime.mjs → rslib-runtime~0.mjs} +0 -0
@@ -7,7 +7,6 @@ import { mergeDataPlatformOptions } from './envelope';
7
7
  import { createHttpApiHandler } from './http';
8
8
  import { createRpcApiHandler } from './rpc';
9
9
  import type {
10
- EffectApiPromiseClientFromApi,
11
10
  EffectBffDefinition,
12
11
  EffectBffHandlerFactory,
13
12
  EffectBffRuntime,
@@ -51,55 +50,12 @@ export function defineEffectBff<
51
50
  validateRequest: options?.validateRequest,
52
51
  });
53
52
  });
54
- const client = createLoaderMaterializedClientPlaceholder<TApi>();
55
53
  return {
56
54
  ...definition,
57
55
  createHandler,
58
- client,
59
56
  };
60
57
  }
61
58
 
62
- const LOADER_CLIENT_IGNORED_KEYS = new Set<PropertyKey>([
63
- 'then',
64
- 'catch',
65
- 'finally',
66
- 'toJSON',
67
- '$$typeof',
68
- ]);
69
-
70
- /**
71
- * `defineEffectBff(...).client` is only materialized when the entry module
72
- * is imported through the `@api/index` transform (the webpack/rspack
73
- * loader swaps the module for generated client code). Importing the entry
74
- * directly (server code, scripts, tests) used to return a `client` typed as
75
- * fully functional but `undefined` at runtime — a bare TypeError with zero
76
- * explanation. This placeholder keeps the type contract while failing with
77
- * an actionable error on first property access.
78
- */
79
- function createLoaderMaterializedClientPlaceholder<
80
- TApi extends HttpApi.Constraint,
81
- >(): EffectApiPromiseClientFromApi<TApi> {
82
- const explain = (property: PropertyKey): never => {
83
- throw new Error(
84
- `[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.`,
85
- );
86
- };
87
-
88
- return new Proxy(Object.create(null), {
89
- get(_target, property) {
90
- // Keep async/inspection protocols (await, console.log, React internals)
91
- // from throwing so the placeholder stays inert until really used.
92
- if (
93
- typeof property === 'symbol' ||
94
- LOADER_CLIENT_IGNORED_KEYS.has(property)
95
- ) {
96
- return undefined;
97
- }
98
- return explain(property);
99
- },
100
- }) as EffectApiPromiseClientFromApi<TApi>;
101
- }
102
-
103
59
  export function defineEffectRpcBff<
104
60
  TRpcs extends Rpc.Any = Rpc.Any,
105
61
  TLayer extends EffectRpcRuntimeLayer<TRpcs> = EffectRpcRuntimeLayer<TRpcs>,
@@ -66,8 +66,8 @@ export function createHttpApiHandler<
66
66
  ) => {
67
67
  // Policy seam first: every HttpApi request, direct or batched item,
68
68
  // passes through here, so batch fan-out cannot bypass validator. The
69
- // interceptor receives the original request and may own malformed or
70
- // legacy payloads; delegated requests still pass through body validation.
69
+ // interceptor receives the original request; delegated requests still
70
+ // pass through body validation.
71
71
  const policyDenial = options.validateRequest?.(request);
72
72
  if (policyDenial) {
73
73
  return policyDenial;
@@ -77,22 +77,6 @@ export type EffectRpcBffHandlerOptions = Pick<
77
77
  | 'disableFatalDefects'
78
78
  >;
79
79
 
80
- type EffectApiPromiseClient<TClient> = {
81
- [GroupName in keyof TClient]: {
82
- [EndpointName in keyof TClient[GroupName]]: TClient[GroupName][EndpointName] extends (
83
- ...args: infer TArgs
84
- ) => infer TResult
85
- ? TResult extends EffectType.Effect<unknown, unknown, unknown>
86
- ? (
87
- ...args: TArgs
88
- ) => Promise<
89
- Exclude<EffectType.Success<TResult>, readonly [unknown, unknown]>
90
- >
91
- : never
92
- : never;
93
- };
94
- };
95
-
96
80
  export type EffectApiClientFromApi<
97
81
  TApi extends HttpApi.Constraint = HttpApi.Top,
98
82
  > =
@@ -104,10 +88,6 @@ export type EffectApiClientFromApi<
104
88
  >
105
89
  : never;
106
90
 
107
- export type EffectApiPromiseClientFromApi<
108
- TApi extends HttpApi.Constraint = HttpApi.Top,
109
- > = EffectApiPromiseClient<EffectApiClientFromApi<TApi>>;
110
-
111
91
  export type EffectBffDefinition<
112
92
  TApi extends HttpApi.Constraint = HttpApi.Top,
113
93
  TLayer extends EffectRuntimeLayer = EffectRuntimeLayer,
@@ -147,12 +127,6 @@ export type EffectDataPlatformBatchOptions = {
147
127
  * Defaults to `65536` (64KiB).
148
128
  */
149
129
  maxBatchBytes?: number;
150
- /**
151
- * Client-side micro-batch flush window in milliseconds.
152
- * Server runtime ignores this value and passes it through for codegen.
153
- * Defaults to `8`.
154
- */
155
- flushIntervalMs?: number;
156
130
  /**
157
131
  * Maximum per-batch internal request concurrency.
158
132
  * Defaults to `4`.
@@ -241,7 +215,6 @@ export type EffectBffRuntime<
241
215
  TLayer extends EffectRuntimeLayer = EffectRuntimeLayer,
242
216
  > = {
243
217
  createHandler: EffectBffHandlerFactory<TApi, TLayer>;
244
- client: EffectApiPromiseClientFromApi<TApi>;
245
218
  };
246
219
 
247
220
  export type EffectBffOpenApiConfig =
@@ -14,7 +14,6 @@ export { defineEffectBff, defineEffectRpcBff } from './handler/definition';
14
14
  export { createHttpApiHandler } from './handler/http';
15
15
  export type {
16
16
  EffectApiClientFromApi,
17
- EffectApiPromiseClientFromApi,
18
17
  EffectBffDefinition,
19
18
  EffectBffHandlerFactory,
20
19
  EffectBffOpenApiConfig,
@@ -67,7 +67,7 @@ function shareDispose(dispose: () => Promise<void>) {
67
67
  };
68
68
  }
69
69
 
70
- function rejectLegacyEffectModuleShape(
70
+ function rejectUnsupportedEffectModuleShape(
71
71
  options: ResolveEffectBffModuleHandlerOptions,
72
72
  shape: string,
73
73
  ) {
@@ -119,8 +119,8 @@ function resolveClassifiedEffectBffModuleHandler(
119
119
  return null;
120
120
  }
121
121
 
122
- if (facts.legacyShape) {
123
- if (rejectLegacyEffectModuleShape(options, facts.legacyShape)) {
122
+ if (facts.unsupportedShape) {
123
+ if (rejectUnsupportedEffectModuleShape(options, facts.unsupportedShape)) {
124
124
  return null;
125
125
  }
126
126
  }
@@ -137,7 +137,7 @@ function resolveClassifiedEffectBffModuleHandler(
137
137
  }
138
138
 
139
139
  if (facts.api === undefined || !facts.hasRuntimeLayer) {
140
- rejectLegacyEffectModuleShape(
140
+ rejectUnsupportedEffectModuleShape(
141
141
  options,
142
142
  'unbranded `createHandler` export',
143
143
  );
@@ -6,7 +6,7 @@ import {
6
6
  BFF_TRACEPARENT_HEADER,
7
7
  type OperationContext,
8
8
  parseTraceparent,
9
- } from '@modern-js/create-request';
9
+ } from '@modern-js/runtime-extensions/request-context';
10
10
 
11
11
  export type EffectContext = {
12
12
  request: Request;
@@ -0,0 +1,109 @@
1
+ import {
2
+ BFF_ENVELOPE_HEADER,
3
+ BFF_OPERATION_CONTEXT_DETAIL_HEADER,
4
+ BFF_OPERATION_CONTEXT_HEADER,
5
+ resolveCrossProjectRequestObservation,
6
+ } from '@modern-js/server-runtime-extensions/bff-policy';
7
+ import * as Effect from 'effect/Effect';
8
+ import * as Schema from 'effect/Schema';
9
+
10
+ const encodeJson = Schema.encodeSync(Schema.fromJsonString(Schema.Unknown));
11
+
12
+ import { HttpClient, HttpClientRequest } from 'effect/unstable/http';
13
+ import { HttpApi, type HttpApiGroup } from 'effect/unstable/httpapi';
14
+
15
+ export interface EffectCrossProjectClientOptions {
16
+ requestId: string;
17
+ operationVersion: number;
18
+ /** Server mount path, independent of the API origin. */
19
+ prefix: string;
20
+ }
21
+
22
+ /** Native transport middleware; endpoint encoding and inference stay in Effect. */
23
+ export function withCrossProjectPolicy<
24
+ Id extends string,
25
+ Groups extends HttpApiGroup.Constraint,
26
+ >(
27
+ api: HttpApi.HttpApi<Id, Groups>,
28
+ options: EffectCrossProjectClientOptions,
29
+ client: HttpClient.HttpClient,
30
+ ): HttpClient.HttpClient {
31
+ const contracts: Record<
32
+ string,
33
+ { operationId: string; name: string; method: string; routePath: string }
34
+ > = {};
35
+ const prefix = options.prefix.replace(/\/$/, '');
36
+ HttpApi.reflect(api, {
37
+ onGroup: () => {},
38
+ onEndpoint: ({ endpoint }) => {
39
+ const routePath =
40
+ `${prefix}${endpoint.path === '/' ? '' : endpoint.path}` || '/';
41
+ const name = endpoint.identifier;
42
+ contracts[`${endpoint.method}:${routePath}`] = {
43
+ operationId: `${options.requestId}:${name}`,
44
+ name,
45
+ method: endpoint.method,
46
+ routePath,
47
+ };
48
+ },
49
+ });
50
+ return client.pipe(
51
+ HttpClient.mapRequestEffect(request => {
52
+ const observed = resolveCrossProjectRequestObservation(
53
+ {
54
+ method: request.method,
55
+ pathname: new URL(request.url, 'http://effect.invalid').pathname,
56
+ },
57
+ { expectedOperationContracts: contracts },
58
+ );
59
+ const contract =
60
+ observed && contracts[`${observed.method}:${observed.routePath}`];
61
+ if (contract === undefined) {
62
+ return Effect.die(
63
+ new Error(
64
+ '[BFF][Effect] Request has no matching shared operation contract.',
65
+ ),
66
+ );
67
+ }
68
+ return Effect.gen(function* () {
69
+ // Canonical field order matches the server's route-identity SHA-256.
70
+ const input = encodeJson({
71
+ httpMethod: contract.method,
72
+ name: contract.name,
73
+ requestId: options.requestId,
74
+ routePath: contract.routePath,
75
+ });
76
+ const digest = yield* Effect.promise(() =>
77
+ globalThis.crypto.subtle.digest(
78
+ 'SHA-256',
79
+ new TextEncoder().encode(input),
80
+ ),
81
+ );
82
+ const schemaHash = Array.from(new Uint8Array(digest), value =>
83
+ value.toString(16).padStart(2, '0'),
84
+ ).join('');
85
+ return request.pipe(
86
+ HttpClientRequest.setHeader(
87
+ BFF_ENVELOPE_HEADER,
88
+ encodeJson({ requestId: options.requestId }),
89
+ ),
90
+ HttpClientRequest.setHeader(
91
+ BFF_OPERATION_CONTEXT_HEADER,
92
+ contract.operationId,
93
+ ),
94
+ HttpClientRequest.setHeader(
95
+ BFF_OPERATION_CONTEXT_DETAIL_HEADER,
96
+ encodeJson({
97
+ requestId: options.requestId,
98
+ operationId: contract.operationId,
99
+ method: contract.method,
100
+ routePath: contract.routePath,
101
+ schemaHash,
102
+ operationVersion: options.operationVersion,
103
+ }),
104
+ ),
105
+ );
106
+ });
107
+ }),
108
+ );
109
+ }
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  createRequestContextHeaders,
4
4
  type RequestContextInput,
5
- } from '@modern-js/create-request';
5
+ } from '@modern-js/runtime-extensions/request-context';
6
6
  import * as Data from 'effect/Data';
7
7
  import * as Effect from 'effect/Effect';
8
8
  import * as Exit from 'effect/Exit';
@@ -30,11 +30,16 @@ import {
30
30
  } from 'effect/unstable/rpc';
31
31
 
32
32
  import { getRpcSerializationLayer } from '../effect/rpcSerialization';
33
+ import {
34
+ type EffectCrossProjectClientOptions,
35
+ withCrossProjectPolicy,
36
+ } from './cross-project';
33
37
 
34
38
  export * as Effect from 'effect/Effect';
35
39
  export * as Layer from 'effect/Layer';
36
40
  export * as Schema from 'effect/Schema';
37
41
  export * as HttpClientError from 'effect/unstable/http/HttpClientError';
42
+ export type { EffectCrossProjectClientOptions } from './cross-project';
38
43
  export {
39
44
  HttpApi,
40
45
  HttpApiClient,
@@ -49,6 +54,7 @@ export {
49
54
  };
50
55
 
51
56
  export type EffectHttpApiClientOptions = {
57
+ crossProject?: EffectCrossProjectClientOptions;
52
58
  baseUrl?: URL | string;
53
59
  requestContext?: RequestContextInput;
54
60
  transformClient?: (client: HttpClient.HttpClient) => HttpClient.HttpClient;
@@ -233,9 +239,13 @@ export function makeEffectHttpApiClient<
233
239
  }),
234
240
  );
235
241
 
242
+ const policyClient =
243
+ options?.crossProject !== undefined
244
+ ? withCrossProjectPolicy(api, options.crossProject, contextClient)
245
+ : contextClient;
236
246
  return typeof options?.transformClient === 'function'
237
- ? options.transformClient(contextClient)
238
- : contextClient;
247
+ ? options.transformClient(policyClient)
248
+ : policyClient;
239
249
  };
240
250
 
241
251
  return HttpApiClient.make(api, {
@@ -0,0 +1,102 @@
1
+ import { Schema } from 'effect';
2
+
3
+ const MicroVerticalAppIdSchema = Schema.String.pipe(
4
+ Schema.brand('MicroVerticalAppId'),
5
+ Schema.decodeTo(Schema.String),
6
+ );
7
+ const MicroVerticalUnitIdSchema = Schema.String.pipe(
8
+ Schema.brand('MicroVerticalUnitId'),
9
+ Schema.decodeTo(Schema.String),
10
+ );
11
+ const MicroVerticalOperationIdSchema = Schema.String.pipe(
12
+ Schema.brand('MicroVerticalOperationId'),
13
+ Schema.decodeTo(Schema.String),
14
+ );
15
+ const MicroVerticalTraceIdSchema = Schema.String.pipe(
16
+ Schema.brand('MicroVerticalTraceId'),
17
+ Schema.decodeTo(Schema.String),
18
+ );
19
+
20
+ export const MicroVerticalBuildMarkerSchema = Schema.Struct({
21
+ appId: MicroVerticalAppIdSchema,
22
+ build: Schema.String,
23
+ buildMarker: Schema.String,
24
+ deployProfile: Schema.String,
25
+ packageName: Schema.String,
26
+ sourceRevision: Schema.String,
27
+ surface: Schema.String,
28
+ unitId: MicroVerticalUnitIdSchema,
29
+ version: Schema.String,
30
+ });
31
+ export type MicroVerticalBuildMarker =
32
+ typeof MicroVerticalBuildMarkerSchema.Type;
33
+
34
+ export const MicroVerticalReadinessSchema = Schema.Struct({
35
+ checks: Schema.Struct({
36
+ api: Schema.Literal('ready'),
37
+ moduleFederation: Schema.Literal('ready'),
38
+ ssr: Schema.Literal('ready'),
39
+ translations: Schema.Literal('ready'),
40
+ }),
41
+ marker: MicroVerticalBuildMarkerSchema,
42
+ status: Schema.Literal('ready'),
43
+ versionSkew: Schema.Literal('none'),
44
+ });
45
+ export type MicroVerticalReadiness = typeof MicroVerticalReadinessSchema.Type;
46
+
47
+ export const MicroVerticalOperationSourceSchema = Schema.Literals([
48
+ 'client',
49
+ 'server',
50
+ 'generated-client',
51
+ 'effect-adapter',
52
+ 'data-platform',
53
+ 'unknown',
54
+ ]);
55
+ export type MicroVerticalOperationSource =
56
+ typeof MicroVerticalOperationSourceSchema.Type;
57
+
58
+ export const MicroVerticalOperationContextSchema = Schema.Struct({
59
+ method: Schema.String,
60
+ operationId: MicroVerticalOperationIdSchema,
61
+ routePath: Schema.String,
62
+ source: MicroVerticalOperationSourceSchema,
63
+ traceId: Schema.optionalKey(MicroVerticalTraceIdSchema),
64
+ });
65
+ export type MicroVerticalOperationContext =
66
+ typeof MicroVerticalOperationContextSchema.Type;
67
+
68
+ export const createMicroVerticalOperationContext = <
69
+ const Method extends string,
70
+ const OperationId extends string,
71
+ const RoutePath extends string,
72
+ >(input: {
73
+ readonly method: Method;
74
+ readonly operationId: OperationId;
75
+ readonly routePath: RoutePath;
76
+ // eslint-disable-next-line effect-native/no-threaded-correlation-parameter -- This pure browser-safe contract deliberately carries optional trace metadata; it does not perform ambient request work.
77
+ readonly traceId?: string;
78
+ }): Readonly<typeof input & { source: 'generated-client' }> => {
79
+ const context = {
80
+ method: input.method,
81
+ operationId: input.operationId,
82
+ routePath: input.routePath,
83
+ source: 'generated-client' as const,
84
+ };
85
+ return input.traceId === undefined
86
+ ? context
87
+ : { ...context, traceId: input.traceId };
88
+ };
89
+
90
+ export const microVerticalOperationAttributes = (
91
+ operationContext: MicroVerticalOperationContext,
92
+ ) => {
93
+ const attributes = {
94
+ 'modernjs.operation.id': operationContext.operationId,
95
+ 'modernjs.operation.method': operationContext.method,
96
+ 'modernjs.operation.route': operationContext.routePath,
97
+ 'modernjs.operation.source': operationContext.source,
98
+ };
99
+ return operationContext.traceId === undefined
100
+ ? attributes
101
+ : { ...attributes, 'modernjs.trace.id': operationContext.traceId };
102
+ };
@@ -1,73 +0,0 @@
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
- configureGeneratedEffectClientRuntime: ()=>configureGeneratedEffectClientRuntime
32
- });
33
- const index_js_namespaceObject = require("../data-platform/index.js");
34
- const external_envelope_js_namespaceObject = require("./envelope.js");
35
- const resolveRuntimeFetch = ()=>'function' == typeof fetch ? fetch.bind(globalThis) : void 0;
36
- const configureGeneratedEffectClientRuntime = (config, configureRequest)=>{
37
- const defaultOrigin = config.defaultOrigin;
38
- if (config.requestId && configureRequest) {
39
- const configurePayload = {
40
- requestId: config.requestId,
41
- requireEnvelope: true,
42
- identityBinding: {
43
- enabled: true,
44
- strict: true
45
- },
46
- operationContract: {
47
- enabled: true,
48
- strict: true,
49
- requireSchemaHash: true,
50
- requireOperationVersion: true
51
- },
52
- setDomain: ()=>(0, external_envelope_js_namespaceObject.resolveOrigin)(defaultOrigin)
53
- };
54
- const runtimeFetch = resolveRuntimeFetch();
55
- if (false !== config.batch.enabled && runtimeFetch) configurePayload.request = (0, index_js_namespaceObject.createDataBatchTransport)({
56
- fetch: runtimeFetch,
57
- endpoint: config.batch.endpoint,
58
- flushIntervalMs: config.batch.flushIntervalMs,
59
- maxBatchSize: config.batch.maxBatchSize,
60
- maxBatchBytes: config.batch.maxBatchBytes,
61
- requestTimeoutMs: config.batch.requestTimeoutMs,
62
- allowedMethods: config.batch.allowedMethods
63
- });
64
- configureRequest(configurePayload);
65
- }
66
- };
67
- exports.configureGeneratedEffectClientRuntime = __webpack_exports__.configureGeneratedEffectClientRuntime;
68
- for(var __rspack_i in __webpack_exports__)if (-1 === [
69
- "configureGeneratedEffectClientRuntime"
70
- ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
71
- Object.defineProperty(exports, '__esModule', {
72
- value: true
73
- });
@@ -1,145 +0,0 @@
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
- prepareEffectRequest: ()=>prepareEffectRequest,
32
- resolveOrigin: ()=>resolveOrigin
33
- });
34
- const index_js_namespaceObject = require("../data-platform/index.js");
35
- const external_guards_js_namespaceObject = require("./guards.js");
36
- const external_request_js_namespaceObject = require("./request.js");
37
- const external_request_context_js_namespaceObject = require("./request-context.js");
38
- const DATA_REQUEST_MODES = new Set([
39
- 'cache-first',
40
- 'stale-while-revalidate',
41
- 'network-only'
42
- ]);
43
- const DATA_MUTATION_MODES = new Set([
44
- 'optimistic',
45
- 'pessimistic',
46
- 'fire-and-forget'
47
- ]);
48
- const isDataRequestMode = (value)=>'string' == typeof value && DATA_REQUEST_MODES.has(value);
49
- const isDataMutationMode = (value)=>'string' == typeof value && DATA_MUTATION_MODES.has(value);
50
- const normalizeOrigin = (value)=>{
51
- if ('string' != typeof value || 0 === value.length) return;
52
- try {
53
- return new URL(value).origin;
54
- } catch {
55
- return;
56
- }
57
- };
58
- const resolveOrigin = (defaultOrigin)=>{
59
- if ("u" > typeof window && window.location && 'string' == typeof window.location.origin && window.location.origin) return window.location.origin;
60
- const globalLocation = globalThis?.location;
61
- if (globalLocation && 'string' == typeof globalLocation.origin && globalLocation.origin) return globalLocation.origin;
62
- return defaultOrigin;
63
- };
64
- const resolveTargetOrigin = (dataPlatform, defaultOrigin)=>{
65
- const explicitTargetOrigin = (0, external_guards_js_namespaceObject.stringOrUndefined)(dataPlatform.targetOrigin) || (0, external_guards_js_namespaceObject.stringOrUndefined)(dataPlatform.endpointOrigin);
66
- if (explicitTargetOrigin) return explicitTargetOrigin;
67
- return defaultOrigin;
68
- };
69
- const shouldAttachEnvelopeHeader = (dataPlatform, defaultOrigin)=>{
70
- if (true === dataPlatform.allowCrossOriginEnvelope) return true;
71
- const currentOrigin = normalizeOrigin(resolveOrigin(defaultOrigin));
72
- const targetOrigin = normalizeOrigin(resolveTargetOrigin(dataPlatform, defaultOrigin));
73
- if (!currentOrigin || !targetOrigin) return true;
74
- return currentOrigin === targetOrigin;
75
- };
76
- const toEnvelopeInput = (normalizedRequest)=>{
77
- const payload = {};
78
- if ((0, external_guards_js_namespaceObject.isRecord)(normalizedRequest.params)) payload.path = normalizedRequest.params;
79
- if ((0, external_guards_js_namespaceObject.isRecord)(normalizedRequest.query)) payload.query = normalizedRequest.query;
80
- if ('data' in normalizedRequest && void 0 !== normalizedRequest.data) payload.data = normalizedRequest.data;
81
- if ('body' in normalizedRequest && void 0 !== normalizedRequest.body) payload.body = normalizedRequest.body;
82
- if ("u" > typeof FormData && normalizedRequest.formData instanceof FormData) payload.formData = Array.from(normalizedRequest.formData.entries()).map(([key, value])=>[
83
- key,
84
- String(value)
85
- ]);
86
- if ("u" > typeof URLSearchParams && normalizedRequest.formUrlencoded instanceof URLSearchParams) payload.formUrlencoded = normalizedRequest.formUrlencoded.toString();
87
- return payload;
88
- };
89
- const prepareEffectRequest = (options)=>{
90
- const { endpoint, operation, request, config, createEffectRequestContext } = options;
91
- const defaultOrigin = config.defaultOrigin;
92
- const normalizedRequest = (0, external_request_context_js_namespaceObject.applyRequestContext)((0, external_request_js_namespaceObject.normalizeRequest)(endpoint.method, request), request, createEffectRequestContext);
93
- const dataPlatform = (0, external_guards_js_namespaceObject.isRecord)(request) && (0, external_guards_js_namespaceObject.isRecord)(request.dataPlatform) ? request.dataPlatform : {};
94
- const strictEnvelope = true === dataPlatform.requireEnvelope || true === dataPlatform.strict;
95
- if (!strictEnvelope && !shouldAttachEnvelopeHeader(dataPlatform, defaultOrigin)) return normalizedRequest;
96
- try {
97
- const namespace = (0, external_guards_js_namespaceObject.stringOrUndefined)(dataPlatform.appNamespace) || config.appNamespace;
98
- const origin = (0, external_guards_js_namespaceObject.stringOrUndefined)(dataPlatform.origin) || resolveOrigin(defaultOrigin);
99
- const envelope = (0, index_js_namespaceObject.createRequestEnvelope)({
100
- operation: {
101
- ...operation,
102
- appNamespace: namespace
103
- },
104
- scope: {
105
- appNamespace: namespace,
106
- origin,
107
- tenantId: (0, external_guards_js_namespaceObject.stringOrUndefined)(dataPlatform.tenantId),
108
- userId: (0, external_guards_js_namespaceObject.stringOrUndefined)(dataPlatform.userId),
109
- sessionId: (0, external_guards_js_namespaceObject.stringOrUndefined)(dataPlatform.sessionId)
110
- },
111
- requestInput: {
112
- method: endpoint.method,
113
- routePath: endpoint.routePath,
114
- payload: toEnvelopeInput(normalizedRequest)
115
- },
116
- requestMode: isDataRequestMode(dataPlatform.requestMode) ? dataPlatform.requestMode : void 0,
117
- mutationMode: isDataMutationMode(dataPlatform.mutationMode) ? dataPlatform.mutationMode : void 0,
118
- selectionPlan: (0, external_guards_js_namespaceObject.isRecord)(dataPlatform.selectionPlan) ? dataPlatform.selectionPlan : void 0,
119
- traceContext: (0, external_guards_js_namespaceObject.isRecord)(dataPlatform.traceContext) ? dataPlatform.traceContext : void 0,
120
- requireTraceContext: true === dataPlatform.requireTraceContext
121
- });
122
- const headerName = (0, external_guards_js_namespaceObject.stringOrUndefined)(dataPlatform.envelopeHeader) || index_js_namespaceObject.DEFAULT_DATA_ENVELOPE_HEADER;
123
- const headers = (0, external_guards_js_namespaceObject.isRecord)(normalizedRequest.headers) ? {
124
- ...normalizedRequest.headers
125
- } : {};
126
- if (false === dataPlatform.batch) headers[index_js_namespaceObject.DEFAULT_DATA_BATCH_HEADER] = 'off';
127
- headers[headerName] = (0, index_js_namespaceObject.encodeRequestEnvelopeHeader)(envelope);
128
- return {
129
- ...normalizedRequest,
130
- headers
131
- };
132
- } catch (error) {
133
- if (strictEnvelope) throw error;
134
- return normalizedRequest;
135
- }
136
- };
137
- exports.prepareEffectRequest = __webpack_exports__.prepareEffectRequest;
138
- exports.resolveOrigin = __webpack_exports__.resolveOrigin;
139
- for(var __rspack_i in __webpack_exports__)if (-1 === [
140
- "prepareEffectRequest",
141
- "resolveOrigin"
142
- ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
143
- Object.defineProperty(exports, '__esModule', {
144
- value: true
145
- });