@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
@@ -1,12 +1,11 @@
1
1
  import type { FileSystem, Path } from 'effect';
2
2
  import * as Context from 'effect/Context';
3
- import type * as EffectType from 'effect/Effect';
4
3
  import type * as Layer from 'effect/Layer';
5
4
  import type { Etag, HttpPlatform, HttpRouter } from 'effect/unstable/http';
6
5
  import type { HttpApi, HttpApiClient, HttpApiGroup } from 'effect/unstable/httpapi';
7
6
  import type { Rpc, RpcGroup } from 'effect/unstable/rpc';
8
- import type { createHttpApiHandler } from './http';
9
- import type { createRpcApiHandler } from './rpc';
7
+ import type { createHttpApiHandler } from './http.js';
8
+ import type { createRpcApiHandler } from './rpc.js';
10
9
  export type EffectRuntimeRequirements = Etag.Generator | FileSystem.FileSystem | HttpPlatform.HttpPlatform | HttpRouter.HttpRouter | HttpRouter.Request<'Error', unknown> | HttpRouter.Request<'GlobalError', unknown> | HttpRouter.Request<'GlobalRequires', unknown> | HttpRouter.Request<'Requires', unknown> | Path.Path;
11
10
  export type EffectRuntimeLayer = Layer.Layer<never, never, EffectRuntimeRequirements>;
12
11
  export declare const toEffectServiceContext: (context: unknown) => Context.Context<any>;
@@ -23,13 +22,7 @@ export type EffectRpcBffDefinition<TRpcs extends Rpc.Any = Rpc.Any, TRpcLayer ex
23
22
  disableFatalDefects?: boolean;
24
23
  };
25
24
  export type EffectRpcBffHandlerOptions = Pick<EffectRpcBffDefinition, 'path' | 'serialization' | 'disableTracing' | 'spanPrefix' | 'spanAttributes' | 'disableFatalDefects'>;
26
- type EffectApiPromiseClient<TClient> = {
27
- [GroupName in keyof TClient]: {
28
- [EndpointName in keyof TClient[GroupName]]: TClient[GroupName][EndpointName] extends (...args: infer TArgs) => infer TResult ? TResult extends EffectType.Effect<unknown, unknown, unknown> ? (...args: TArgs) => Promise<Exclude<EffectType.Success<TResult>, readonly [unknown, unknown]>> : never : never;
29
- };
30
- };
31
25
  export type EffectApiClientFromApi<TApi extends HttpApi.Constraint = HttpApi.Top> = TApi extends HttpApi.HttpApi<infer _ApiId, infer Groups> ? HttpApiClient.Client<Extract<Groups, HttpApiGroup.Constraint>, never, never> : never;
32
- export type EffectApiPromiseClientFromApi<TApi extends HttpApi.Constraint = HttpApi.Top> = EffectApiPromiseClient<EffectApiClientFromApi<TApi>>;
33
26
  export type EffectBffDefinition<TApi extends HttpApi.Constraint = HttpApi.Top, TLayer extends EffectRuntimeLayer = EffectRuntimeLayer, TRpcs extends Rpc.Any = Rpc.Any> = {
34
27
  api: TApi;
35
28
  layer: TLayer;
@@ -63,12 +56,6 @@ export type EffectDataPlatformBatchOptions = {
63
56
  * Defaults to `65536` (64KiB).
64
57
  */
65
58
  maxBatchBytes?: number;
66
- /**
67
- * Client-side micro-batch flush window in milliseconds.
68
- * Server runtime ignores this value and passes it through for codegen.
69
- * Defaults to `8`.
70
- */
71
- flushIntervalMs?: number;
72
59
  /**
73
60
  * Maximum per-batch internal request concurrency.
74
61
  * Defaults to `4`.
@@ -144,10 +131,8 @@ export type EffectBffHandlerFactory<TApi extends HttpApi.Constraint = HttpApi.To
144
131
  }) => ReturnType<typeof createHttpApiHandler>;
145
132
  export type EffectBffRuntime<TApi extends HttpApi.Constraint = HttpApi.Top, TLayer extends EffectRuntimeLayer = EffectRuntimeLayer> = {
146
133
  createHandler: EffectBffHandlerFactory<TApi, TLayer>;
147
- client: EffectApiPromiseClientFromApi<TApi>;
148
134
  };
149
135
  export type EffectBffOpenApiConfig = boolean | {
150
136
  path?: string;
151
137
  };
152
138
  export type EffectRpcBffHandlerFactory<TRpcs extends Rpc.Any = Rpc.Any> = (options?: Partial<EffectRpcBffHandlerOptions>) => ReturnType<typeof createRpcApiHandler<TRpcs>>;
153
- export {};
@@ -8,6 +8,6 @@ export { HttpTraceContext } from 'effect/unstable/http';
8
8
  export * from 'effect/unstable/httpapi';
9
9
  export { HttpApiBuilder } from 'effect/unstable/httpapi';
10
10
  export * from 'effect/unstable/rpc';
11
- export { defineEffectBff, defineEffectRpcBff } from './handler/definition';
12
- export { createHttpApiHandler } from './handler/http';
13
- export type { EffectApiClientFromApi, EffectApiPromiseClientFromApi, EffectBffDefinition, EffectBffHandlerFactory, EffectBffOpenApiConfig, EffectBffRuntime, EffectDataPlatformBatchOptions, EffectDataPlatformSelectionValidationOptions, EffectDataPlatformValidationOptions, EffectRequestValidator, EffectRpcBffDefinition, EffectRpcBffHandlerFactory, EffectRpcBffHandlerOptions, EffectRpcRuntimeLayer, EffectRpcSerialization, EffectRuntimeLayer, EffectRuntimeRequirements, } from './handler/types';
11
+ export { defineEffectBff, defineEffectRpcBff } from './handler/definition.js';
12
+ export { createHttpApiHandler } from './handler/http.js';
13
+ export type { EffectApiClientFromApi, EffectBffDefinition, EffectBffHandlerFactory, EffectBffOpenApiConfig, EffectBffRuntime, EffectDataPlatformBatchOptions, EffectDataPlatformSelectionValidationOptions, EffectDataPlatformValidationOptions, EffectRequestValidator, EffectRpcBffDefinition, EffectRpcBffHandlerFactory, EffectRpcBffHandlerOptions, EffectRpcRuntimeLayer, EffectRpcSerialization, EffectRuntimeLayer, EffectRuntimeRequirements, } from './handler/types.js';
@@ -1,6 +1,6 @@
1
1
  export * as OpenTelemetry from '@effect/opentelemetry';
2
- export { type CreateEffectOperationContextOptions, createEffectOperationContext, type EffectContext, runWithEffectContext, useEffectContext, useOperationContext, } from './context';
3
- export { createEffectBffEdgeHandler, createEffectBffTestHandler, dispatchEffectBffRequest, } from './edge';
4
- export * from './endpoint-contracts';
5
- export * from './handler';
6
- export { type EffectApiModule, type EffectBffHandlerFactory, type EffectBffRequestHandler, resolveEffectBffModuleHandler, } from './module';
2
+ export { type CreateEffectOperationContextOptions, createEffectOperationContext, type EffectContext, runWithEffectContext, useEffectContext, useOperationContext, } from './context.js';
3
+ export { createEffectBffEdgeHandler, createEffectBffTestHandler, dispatchEffectBffRequest, } from './edge.js';
4
+ export * from './endpoint-contracts.js';
5
+ export * from './handler.js';
6
+ export { type EffectApiModule, type EffectBffHandlerFactory, type EffectBffRequestHandler, resolveEffectBffModuleHandler, } from './module.js';
@@ -1,6 +1,6 @@
1
1
  import type * as EffectServiceContext from 'effect/Context';
2
- import { type EffectBffOpenApiConfig, type EffectDataPlatformValidationOptions, type EffectRequestValidator } from './handler';
3
- import type { EffectContext } from './operation-context';
2
+ import { type EffectBffOpenApiConfig, type EffectDataPlatformValidationOptions, type EffectRequestValidator } from './handler.js';
3
+ import type { EffectContext } from './operation-context.js';
4
4
  export type EffectBffRequestHandler = (request: Request, context?: EffectServiceContext.Context<any> | EffectContext) => Promise<Response> | Response;
5
5
  export type EffectBffHandlerFactory = (options?: {
6
6
  openapi?: EffectBffOpenApiConfig;
@@ -1,4 +1,4 @@
1
- import { type OperationContext } from '@modern-js/create-request';
1
+ import { type OperationContext } from '@modern-js/runtime-extensions/request-context';
2
2
  export type EffectContext = {
3
3
  request: Request;
4
4
  env: Record<string, unknown>;
@@ -1,3 +1,3 @@
1
1
  import { RpcSerialization } from 'effect/unstable/rpc';
2
- import type { EffectRpcSerialization } from './handler/types';
2
+ import type { EffectRpcSerialization } from './handler/types.js';
3
3
  export declare function getRpcSerializationLayer(serialization: EffectRpcSerialization | undefined): import("effect/Layer").Layer<RpcSerialization.RpcSerialization, never, never>;
@@ -0,0 +1,10 @@
1
+ import { HttpClient } from 'effect/unstable/http';
2
+ import { HttpApi, type HttpApiGroup } from 'effect/unstable/httpapi';
3
+ export interface EffectCrossProjectClientOptions {
4
+ requestId: string;
5
+ operationVersion: number;
6
+ /** Server mount path, independent of the API origin. */
7
+ prefix: string;
8
+ }
9
+ /** Native transport middleware; endpoint encoding and inference stay in Effect. */
10
+ export declare function withCrossProjectPolicy<Id extends string, Groups extends HttpApiGroup.Constraint>(api: HttpApi.HttpApi<Id, Groups>, options: EffectCrossProjectClientOptions, client: HttpClient.HttpClient): HttpClient.HttpClient;
@@ -1,15 +1,18 @@
1
- import { type RequestContextInput } from '@modern-js/create-request';
1
+ import { type RequestContextInput } from '@modern-js/runtime-extensions/request-context';
2
2
  import * as Effect from 'effect/Effect';
3
3
  import * as Layer from 'effect/Layer';
4
4
  import { HttpClient } from 'effect/unstable/http';
5
5
  import { HttpApi, HttpApiClient, HttpApiEndpoint, HttpApiGroup, HttpApiSchema } from 'effect/unstable/httpapi';
6
6
  import { Rpc, RpcClient, RpcGroup, RpcSchema, RpcSerialization } from 'effect/unstable/rpc';
7
+ import { type EffectCrossProjectClientOptions } from './cross-project.js';
7
8
  export * as Effect from 'effect/Effect';
8
9
  export * as Layer from 'effect/Layer';
9
10
  export * as Schema from 'effect/Schema';
10
11
  export * as HttpClientError from 'effect/unstable/http/HttpClientError';
12
+ export type { EffectCrossProjectClientOptions } from './cross-project.js';
11
13
  export { HttpApi, HttpApiClient, HttpApiEndpoint, HttpApiGroup, HttpApiSchema, Rpc, RpcClient, RpcGroup, RpcSchema, RpcSerialization, };
12
14
  export type EffectHttpApiClientOptions = {
15
+ crossProject?: EffectCrossProjectClientOptions;
13
16
  baseUrl?: URL | string;
14
17
  requestContext?: RequestContextInput;
15
18
  transformClient?: (client: HttpClient.HttpClient) => HttpClient.HttpClient;
@@ -1,3 +1,3 @@
1
- export * as DataPlatform from './data-platform';
2
- export * from './effect';
3
- export * as EffectClient from './effect-client';
1
+ export * as DataPlatform from './data-platform/index.js';
2
+ export * from './effect/index.js';
3
+ export * as EffectClient from './effect-client/index.js';
@@ -0,0 +1,65 @@
1
+ import { Schema } from 'effect';
2
+ export declare const MicroVerticalBuildMarkerSchema: Schema.Struct<{
3
+ readonly appId: Schema.compose<Schema.String, Schema.brand<Schema.String, "MicroVerticalAppId">>;
4
+ readonly build: Schema.String;
5
+ readonly buildMarker: Schema.String;
6
+ readonly deployProfile: Schema.String;
7
+ readonly packageName: Schema.String;
8
+ readonly sourceRevision: Schema.String;
9
+ readonly surface: Schema.String;
10
+ readonly unitId: Schema.compose<Schema.String, Schema.brand<Schema.String, "MicroVerticalUnitId">>;
11
+ readonly version: Schema.String;
12
+ }>;
13
+ export type MicroVerticalBuildMarker = typeof MicroVerticalBuildMarkerSchema.Type;
14
+ export declare const MicroVerticalReadinessSchema: Schema.Struct<{
15
+ readonly checks: Schema.Struct<{
16
+ readonly api: Schema.Literal<"ready">;
17
+ readonly moduleFederation: Schema.Literal<"ready">;
18
+ readonly ssr: Schema.Literal<"ready">;
19
+ readonly translations: Schema.Literal<"ready">;
20
+ }>;
21
+ readonly marker: Schema.Struct<{
22
+ readonly appId: Schema.compose<Schema.String, Schema.brand<Schema.String, "MicroVerticalAppId">>;
23
+ readonly build: Schema.String;
24
+ readonly buildMarker: Schema.String;
25
+ readonly deployProfile: Schema.String;
26
+ readonly packageName: Schema.String;
27
+ readonly sourceRevision: Schema.String;
28
+ readonly surface: Schema.String;
29
+ readonly unitId: Schema.compose<Schema.String, Schema.brand<Schema.String, "MicroVerticalUnitId">>;
30
+ readonly version: Schema.String;
31
+ }>;
32
+ readonly status: Schema.Literal<"ready">;
33
+ readonly versionSkew: Schema.Literal<"none">;
34
+ }>;
35
+ export type MicroVerticalReadiness = typeof MicroVerticalReadinessSchema.Type;
36
+ export declare const MicroVerticalOperationSourceSchema: Schema.Literals<readonly ["client", "server", "generated-client", "effect-adapter", "data-platform", "unknown"]>;
37
+ export type MicroVerticalOperationSource = typeof MicroVerticalOperationSourceSchema.Type;
38
+ export declare const MicroVerticalOperationContextSchema: Schema.Struct<{
39
+ readonly method: Schema.String;
40
+ readonly operationId: Schema.compose<Schema.String, Schema.brand<Schema.String, "MicroVerticalOperationId">>;
41
+ readonly routePath: Schema.String;
42
+ readonly source: Schema.Literals<readonly ["client", "server", "generated-client", "effect-adapter", "data-platform", "unknown"]>;
43
+ readonly traceId: Schema.optionalKey<Schema.compose<Schema.String, Schema.brand<Schema.String, "MicroVerticalTraceId">>>;
44
+ }>;
45
+ export type MicroVerticalOperationContext = typeof MicroVerticalOperationContextSchema.Type;
46
+ export declare const createMicroVerticalOperationContext: <const Method extends string, const OperationId extends string, const RoutePath extends string>(input: {
47
+ readonly method: Method;
48
+ readonly operationId: OperationId;
49
+ readonly routePath: RoutePath;
50
+ readonly traceId?: string;
51
+ }) => Readonly<typeof input & {
52
+ source: 'generated-client';
53
+ }>;
54
+ export declare const microVerticalOperationAttributes: (operationContext: MicroVerticalOperationContext) => {
55
+ 'modernjs.operation.id': string;
56
+ 'modernjs.operation.method': string;
57
+ 'modernjs.operation.route': string;
58
+ 'modernjs.operation.source': "client" | "data-platform" | "effect-adapter" | "generated-client" | "server" | "unknown";
59
+ } | {
60
+ 'modernjs.operation.id': string;
61
+ 'modernjs.operation.method': string;
62
+ 'modernjs.operation.route': string;
63
+ 'modernjs.operation.source': "client" | "data-platform" | "effect-adapter" | "generated-client" | "server" | "unknown";
64
+ 'modernjs.trace.id': string;
65
+ };
package/package.json CHANGED
@@ -18,7 +18,7 @@
18
18
  "modern.js",
19
19
  "ultramodern.js"
20
20
  ],
21
- "version": "3.8.3-ultramodern.6",
21
+ "version": "3.9.0-ultramodern.10",
22
22
  "files": [
23
23
  "dist",
24
24
  "src"
@@ -67,14 +67,14 @@
67
67
  "import": "./dist/esm/effect-client/index.mjs",
68
68
  "default": "./dist/esm/effect-client/index.mjs"
69
69
  },
70
- "./effect-client-runtime": {
71
- "types": "./dist/types/effect-client/runtime.d.ts",
70
+ "./microvertical-api": {
71
+ "types": "./dist/types/microvertical-api.d.ts",
72
72
  "node": {
73
- "import": "./dist/esm-node/effect-client/runtime.mjs",
74
- "require": "./dist/cjs/effect-client/runtime.js"
73
+ "import": "./dist/esm-node/microvertical-api.mjs",
74
+ "require": "./dist/cjs/microvertical-api.js"
75
75
  },
76
- "import": "./dist/esm/effect-client/runtime.mjs",
77
- "default": "./dist/esm/effect-client/runtime.mjs"
76
+ "import": "./dist/esm/microvertical-api.mjs",
77
+ "default": "./dist/esm/microvertical-api.mjs"
78
78
  },
79
79
  "./data-platform": {
80
80
  "types": "./dist/types/data-platform/index.d.ts",
@@ -84,6 +84,14 @@
84
84
  },
85
85
  "import": "./dist/esm/data-platform/index.mjs",
86
86
  "default": "./dist/esm/data-platform/index.mjs"
87
+ },
88
+ "./assembly": {
89
+ "types": "./dist/types/assembly.d.ts",
90
+ "node": {
91
+ "import": "./dist/esm-node/assembly.mjs",
92
+ "require": "./dist/cjs/assembly.js"
93
+ },
94
+ "default": "./dist/esm/assembly.mjs"
87
95
  }
88
96
  },
89
97
  "typesVersions": {
@@ -104,13 +112,17 @@
104
112
  "./dist/types/effect-client/index.d.ts",
105
113
  "./src/effect-client/index.ts"
106
114
  ],
107
- "effect-client-runtime": [
108
- "./dist/types/effect-client/runtime.d.ts",
109
- "./src/effect-client/runtime.ts"
115
+ "microvertical-api": [
116
+ "./dist/types/microvertical-api.d.ts",
117
+ "./src/microvertical-api.ts"
110
118
  ],
111
119
  "data-platform": [
112
120
  "./dist/types/data-platform/index.d.ts",
113
121
  "./src/data-platform/index.ts"
122
+ ],
123
+ "assembly": [
124
+ "./dist/types/assembly.d.ts",
125
+ "./src/assembly.ts"
114
126
  ]
115
127
  }
116
128
  },
@@ -118,17 +130,18 @@
118
130
  "node": ">=26.7.0"
119
131
  },
120
132
  "dependencies": {
121
- "@modern-js/bff-core": "npm:@bleedingdev/modern-js-bff-core@3.8.3-ultramodern.6",
122
- "@modern-js/create-request": "npm:@bleedingdev/modern-js-create-request@3.8.3-ultramodern.6",
123
- "@modern-js/runtime-extensions": "npm:@bleedingdev/modern-js-runtime-extensions@3.8.3-ultramodern.6",
133
+ "@modern-js/bff-core": "npm:@bleedingdev/modern-js-bff-core@3.9.0-ultramodern.10",
134
+ "@modern-js/create-request": "npm:@bleedingdev/modern-js-create-request@3.9.0-ultramodern.10",
135
+ "@modern-js/runtime-extensions": "npm:@bleedingdev/modern-js-runtime-extensions@3.9.0-ultramodern.10",
136
+ "@modern-js/server-runtime-extensions": "npm:@bleedingdev/modern-js-server-runtime-extensions@3.9.0-ultramodern.10",
124
137
  "@opentelemetry/api": "1.9.1",
125
- "@opentelemetry/api-logs": "0.220.0",
126
- "@opentelemetry/resources": "2.9.0",
127
- "@opentelemetry/sdk-logs": "0.220.0",
128
- "@opentelemetry/sdk-metrics": "2.9.0",
129
- "@opentelemetry/sdk-trace-base": "2.9.0",
130
- "@opentelemetry/sdk-trace-node": "2.9.0",
131
- "@opentelemetry/sdk-trace-web": "2.9.0",
138
+ "@opentelemetry/api-logs": "0.222.0",
139
+ "@opentelemetry/resources": "2.11.0",
140
+ "@opentelemetry/sdk-logs": "0.222.0",
141
+ "@opentelemetry/sdk-metrics": "2.11.0",
142
+ "@opentelemetry/sdk-trace-base": "2.11.0",
143
+ "@opentelemetry/sdk-trace-node": "2.11.0",
144
+ "@opentelemetry/sdk-trace-web": "2.11.0",
132
145
  "@opentelemetry/semantic-conventions": "1.43.0"
133
146
  },
134
147
  "peerDependencies": {
@@ -145,9 +158,9 @@
145
158
  },
146
159
  "devDependencies": {
147
160
  "@effect/opentelemetry": "4.0.0-rc.112",
148
- "@rslib/core": "0.23.2",
161
+ "@rslib/core": "1.0.0",
149
162
  "@scripts/rstest-config": "2.66.0",
150
- "@types/node": "^26.2.0",
163
+ "@types/node": "^26.4.1",
151
164
  "@types/react": "^19.2.18",
152
165
  "@typescript/native-preview": "7.0.0-dev.20260707.2",
153
166
  "effect": "4.0.0-rc.112"
@@ -0,0 +1,43 @@
1
+ /** Server-only assembly for the invariant tail of a strict Effect BFF runtime factory. */
2
+ import * as Layer from 'effect/Layer';
3
+ import type { HttpApi, HttpApiGroup } from 'effect/unstable/httpapi';
4
+ import { HttpApiBuilder } from 'effect/unstable/httpapi';
5
+ import { defineEffectBff } from './effect/handler/definition';
6
+ import type { EffectRuntimeRequirements } from './effect/handler/types';
7
+
8
+ export interface EffectBffRuntimeAssembly<
9
+ ApiId extends string,
10
+ Groups extends HttpApiGroup.Constraint,
11
+ HandlerRequirements extends EffectRuntimeRequirements,
12
+ TransportRequirements extends EffectRuntimeRequirements = never,
13
+ > {
14
+ readonly api: HttpApi.HttpApi<ApiId, Groups>;
15
+ readonly handlers: Layer.Layer<
16
+ HttpApiGroup.ToService<ApiId, Groups>,
17
+ never,
18
+ HandlerRequirements
19
+ >;
20
+ readonly transport?: Layer.Layer<never, never, TransportRequirements>;
21
+ }
22
+
23
+ export const assembleEffectBffRuntime = <
24
+ ApiId extends string,
25
+ Groups extends HttpApiGroup.Constraint,
26
+ HandlerRequirements extends EffectRuntimeRequirements,
27
+ TransportRequirements extends EffectRuntimeRequirements = never,
28
+ >({
29
+ api,
30
+ handlers,
31
+ transport,
32
+ }: EffectBffRuntimeAssembly<
33
+ ApiId,
34
+ Groups,
35
+ HandlerRequirements,
36
+ TransportRequirements
37
+ >) => {
38
+ const apiLayer = HttpApiBuilder.layer(api).pipe(Layer.provide(handlers));
39
+ const layer =
40
+ transport === undefined ? apiLayer : apiLayer.pipe(Layer.merge(transport));
41
+
42
+ return defineEffectBff({ api, layer });
43
+ };
@@ -307,15 +307,14 @@ export function createBatchTransportQueue({
307
307
  abortBatchIfUnused?.();
308
308
  };
309
309
 
310
- const runSingle = (request: QueuedBatchRequest) => {
311
- return runWithSignal(request.lifetime.signal, async () => {
310
+ const runSingle = (request: QueuedBatchRequest) =>
311
+ runWithSignal(request.lifetime.signal, async () => {
312
312
  const response = await baseFetch(
313
313
  request.requestInput,
314
314
  request.requestInit,
315
315
  );
316
316
  return parseResponseLikeCreateRequest(response);
317
317
  });
318
- };
319
318
 
320
319
  const settleRequests = async (
321
320
  items: QueuedBatchRequest[],
@@ -1,5 +1,5 @@
1
1
  // @effect-diagnostics asyncFunction:off globalDate:off globalRandom:off globalTimers:off newPromise:off strictBooleanExpressions:off
2
- import { parseTraceparent } from '@modern-js/create-request';
2
+ import { parseTraceparent } from '@modern-js/runtime-extensions/request-context';
3
3
 
4
4
  import type { TraceContext } from './types';
5
5
 
@@ -3,7 +3,8 @@ import {
3
3
  evaluateCrossProjectPolicy,
4
4
  type NormalizedCrossProjectPolicy,
5
5
  resolveCrossProjectRequestObservation,
6
- } from '@modern-js/bff-core/security/cross-project-policy';
6
+ } from '@modern-js/server-runtime-extensions/bff-policy';
7
+ import * as Effect from 'effect/Effect';
7
8
  import { toHeaderRecord } from '../headers';
8
9
  import {
9
10
  type DispatchEffectBffRequestOptions,
@@ -91,7 +92,6 @@ export {
91
92
  } from './edge-context';
92
93
  export type {
93
94
  EffectApiClientFromApi,
94
- EffectApiPromiseClientFromApi,
95
95
  EffectBffDefinition,
96
96
  EffectBffHandlerFactory,
97
97
  EffectBffOpenApiConfig,
@@ -285,9 +285,11 @@ export async function createEffectBffEdgeDispatcher(
285
285
  disposePromise ??= (async () => {
286
286
  acceptingRequests = false;
287
287
  if (activeDispatches > 0) {
288
- await new Promise<void>(resolve => {
289
- resolveDrain = resolve;
290
- });
288
+ await Effect.runPromise(
289
+ Effect.callback<void>(resume => {
290
+ resolveDrain = () => resume(Effect.void);
291
+ }),
292
+ );
291
293
  }
292
294
  await loaded.dispose?.();
293
295
  })();
@@ -1 +1,2 @@
1
1
  export * from './edge-dispatcher';
2
+ export { createEffectBffEdgeDispatcherFactory } from './generated-entry';
@@ -1,21 +1,9 @@
1
1
  // @effect-diagnostics asyncFunction:off strictBooleanExpressions:off
2
- /**
3
- * Shared Effect HttpApi endpoint reflection used by BOTH sides of the
4
- * cross-project contract:
5
- *
6
- * - the `@modern-js/plugin-bff-extensions/client-generator` package stamps
7
- * each generated operation with a per-endpoint contract hash;
8
- * - the `@modern-js/plugin-bff-extensions/effect-adapter` package derives the
9
- * expected operation-contract map for the cross-project policy from the
10
- * same endpoints.
11
- *
12
- * Keeping route-path normalization and the endpoint -> contract mapping in
13
- * one module is what guarantees the two hashes agree.
14
- */
2
+ /** Shared endpoint normalization and identity hashing for server policy metadata. */
15
3
  import {
16
4
  createOperationContractHash,
17
5
  type OperationContractSource,
18
- } from '@modern-js/bff-core';
6
+ } from '@modern-js/server-runtime-extensions/bff-policy/node';
19
7
  import {
20
8
  classifyEffectBffEntryModule,
21
9
  isValidatorAwareHandlerFactory,
@@ -38,13 +26,7 @@ type HttpApiGroupLike = {
38
26
  };
39
27
 
40
28
  type HttpApiEndpointLike = {
41
- /**
42
- * effect 4.0.0-beta.98 renamed the endpoint `name` property to `identifier`,
43
- * matching `HttpApiGroup`. `name` is kept as a fallback so reflection over an
44
- * older Effect build does not silently degrade to the class name.
45
- */
46
29
  identifier?: unknown;
47
- name?: unknown;
48
30
  method?: unknown;
49
31
  path?: unknown;
50
32
  };
@@ -53,9 +35,6 @@ function resolveEffectEndpointName(endpoint: HttpApiEndpointLike): string {
53
35
  if (typeof endpoint.identifier === 'string' && endpoint.identifier) {
54
36
  return endpoint.identifier;
55
37
  }
56
- if (typeof endpoint.name === 'string' && endpoint.name) {
57
- return endpoint.name;
58
- }
59
38
  return '';
60
39
  }
61
40
 
@@ -168,7 +147,7 @@ export async function extractHttpApiFromModule(
168
147
  isValidatorAwareHandlerFactory,
169
148
  isHttpApi,
170
149
  });
171
- return facts?.legacyShape ||
150
+ return facts?.unsupportedShape ||
172
151
  facts?.api === undefined ||
173
152
  !facts.hasRuntimeLayer ||
174
153
  (facts.createHandler !== undefined && !facts.createHandlerValidatorAware)
@@ -42,8 +42,11 @@ function loadNodeValidatorAwareHandlerFactoryRegistry(): ValidatorAwareHandlerFa
42
42
  }
43
43
  }
44
44
 
45
+ declare const __MODERN_EFFECT_NODE_RUNTIME__: boolean;
46
+
45
47
  const validatorAwareHandlerFactoryRegistry =
46
- process.env.MODERN_EFFECT_NODE_RUNTIME === 'true'
48
+ typeof __MODERN_EFFECT_NODE_RUNTIME__ !== 'undefined' &&
49
+ __MODERN_EFFECT_NODE_RUNTIME__
47
50
  ? loadNodeValidatorAwareHandlerFactoryRegistry()
48
51
  : createLocalValidatorAwareHandlerFactoryRegistry();
49
52
 
@@ -55,11 +58,13 @@ type EffectBffEntryModule = {
55
58
  default?: unknown;
56
59
  };
57
60
 
58
- type LegacyEffectBffEntryShape = '`handler` export' | 'default request handler';
61
+ type UnsupportedEffectBffEntryShape =
62
+ | '`handler` export'
63
+ | 'default request handler';
59
64
 
60
65
  export type EffectBffEntryShapeFacts = {
61
66
  module: EffectBffEntryModule;
62
- legacyShape?: LegacyEffectBffEntryShape;
67
+ unsupportedShape?: UnsupportedEffectBffEntryShape;
63
68
  createHandler?: unknown;
64
69
  createHandlerValidatorAware: boolean;
65
70
  api?: unknown;
@@ -132,7 +137,7 @@ export function classifyEffectBffEntryModule(
132
137
  function createEntryShapeFacts(
133
138
  module: EffectBffEntryModule,
134
139
  predicates: EffectBffEntryShapePredicates,
135
- legacyShape?: LegacyEffectBffEntryShape,
140
+ unsupportedShape?: UnsupportedEffectBffEntryShape,
136
141
  ): EffectBffEntryShapeFacts {
137
142
  const createHandler =
138
143
  typeof module.createHandler === 'function'
@@ -143,7 +148,7 @@ function createEntryShapeFacts(
143
148
 
144
149
  return {
145
150
  module,
146
- legacyShape,
151
+ unsupportedShape,
147
152
  createHandler,
148
153
  createHandlerValidatorAware:
149
154
  createHandler !== undefined &&
@@ -0,0 +1,36 @@
1
+ import {
2
+ createEffectBffEdgeDispatcher,
3
+ type EffectBffEdgeHandlerOptions,
4
+ } from './edge-dispatcher';
5
+
6
+ type OperationContracts = NonNullable<
7
+ EffectBffEdgeHandlerOptions['crossProjectPolicy']
8
+ >['expectedOperationContracts'];
9
+
10
+ export function createEffectBffEdgeDispatcherFactory(
11
+ module: EffectBffEdgeHandlerOptions['module'],
12
+ generatedOperationContracts: OperationContracts,
13
+ ) {
14
+ return (options?: Omit<EffectBffEdgeHandlerOptions, 'module'>) => {
15
+ const policy = options?.crossProjectPolicy;
16
+ const crossProjectPolicy =
17
+ policy === undefined ||
18
+ policy === null ||
19
+ policy.expectedOperationContracts === null ||
20
+ typeof policy.expectedOperationContracts !== 'object' ||
21
+ Array.isArray(policy.expectedOperationContracts)
22
+ ? policy
23
+ : {
24
+ ...policy,
25
+ expectedOperationContracts: {
26
+ ...policy.expectedOperationContracts,
27
+ ...generatedOperationContracts,
28
+ },
29
+ };
30
+ return createEffectBffEdgeDispatcher({
31
+ ...options,
32
+ crossProjectPolicy,
33
+ module,
34
+ });
35
+ };
36
+ }
@@ -1,4 +1,5 @@
1
1
  // @effect-diagnostics anyUnknownInErrorContext:off asyncFunction:off globalDate:off globalTimers:off newPromise:off strictBooleanExpressions:off
2
+ import * as Effect from 'effect/Effect';
2
3
  import {
3
4
  type DataBatchResponsePayload,
4
5
  DEFAULT_DATA_BATCH_HEADER,
@@ -417,14 +418,16 @@ export function createDataPlatformBatchRequestHandler<TContext>(options: {
417
418
  );
418
419
  } catch (error) {
419
420
  if (error instanceof BatchItemTimeoutError) {
420
- console.error({
421
- event: 'bff.batch.item.timeout',
422
- batchId: payload.batchId,
423
- itemId,
424
- method: itemMethod,
425
- path: itemPathname,
426
- errorName: error.name,
427
- });
421
+ Effect.runSync(
422
+ Effect.logError({
423
+ event: 'bff.batch.item.timeout',
424
+ batchId: payload.batchId,
425
+ itemId,
426
+ method: itemMethod,
427
+ path: itemPathname,
428
+ errorName: error.name,
429
+ }),
430
+ );
428
431
  return toBatchItemError(
429
432
  itemId,
430
433
  504,
@@ -435,14 +438,16 @@ export function createDataPlatformBatchRequestHandler<TContext>(options: {
435
438
  return toBatchResponseItem(itemId, error, itemMethod === 'HEAD');
436
439
  }
437
440
 
438
- console.error({
439
- event: 'bff.batch.item.failure',
440
- batchId: payload.batchId,
441
- itemId,
442
- method: itemMethod,
443
- path: itemPathname,
444
- errorName: error instanceof Error ? error.name : 'UnknownError',
445
- });
441
+ Effect.runSync(
442
+ Effect.logError({
443
+ event: 'bff.batch.item.failure',
444
+ batchId: payload.batchId,
445
+ itemId,
446
+ method: itemMethod,
447
+ path: itemPathname,
448
+ errorName: error instanceof Error ? error.name : 'UnknownError',
449
+ }),
450
+ );
446
451
  return toBatchItemError(itemId, 500, 'Internal Server Error');
447
452
  } finally {
448
453
  request.signal.removeEventListener('abort', abortFromBatchRequest);
@@ -1,5 +1,6 @@
1
1
  // @effect-diagnostics anyUnknownInErrorContext:off asyncFunction:off globalDate:off globalTimers:off newPromise:off strictBooleanExpressions:off
2
2
 
3
+ import * as Data from 'effect/Data';
3
4
  import {
4
5
  type DataBatchRequestPayload,
5
6
  type DataBatchResponseItem,
@@ -117,7 +118,14 @@ export function toBatchItemError(
117
118
  };
118
119
  }
119
120
 
120
- export class BatchItemTimeoutError extends Error {}
121
+ export class BatchItemTimeoutError extends Data.TaggedError(
122
+ 'BatchItemTimeoutError',
123
+ )<{ readonly message: string }> {
124
+ constructor(message: string) {
125
+ super({ message });
126
+ this.name = 'Error';
127
+ }
128
+ }
121
129
 
122
130
  export function promiseWithTimeout<T>(
123
131
  effect: Promise<T>,