@bleedingdev/modern-js-bff-effect 3.9.0-ultramodern.9 → 3.9.3-ultramodern.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/assembly.js +2 -2
- package/dist/cjs/data-platform/batch/options.js +48 -0
- package/dist/cjs/data-platform/batch/queue.js +48 -83
- package/dist/cjs/effect/context.js +28 -4
- package/dist/cjs/effect/edge-dispatcher.js +19 -19
- package/dist/cjs/effect/edge.js +26 -6
- package/dist/cjs/effect/entry-shape.js +38 -10
- package/dist/cjs/effect/handler/batch-handler.js +2 -3
- package/dist/cjs/effect/handler/batch.js +0 -9
- package/dist/cjs/effect/handler/http.js +1 -1
- package/dist/cjs/effect/handler/openapi.js +3 -3
- package/dist/cjs/effect/handler/rpc.js +2 -2
- package/dist/cjs/effect/handler.js +26 -26
- package/dist/cjs/effect/index.js +8 -8
- package/dist/cjs/effect/module.js +6 -2
- package/dist/cjs/effect/operation-context.js +3 -7
- package/dist/cjs/effect/rpcSerialization.js +1 -3
- package/dist/cjs/effect-client/cross-project.js +8 -11
- package/dist/cjs/effect-client/index.js +10 -10
- package/dist/cjs/microvertical-api.js +1 -1
- package/dist/esm/assembly.mjs +1 -1
- package/dist/esm/data-platform/batch/options.mjs +10 -0
- package/dist/esm/data-platform/batch/queue.mjs +48 -83
- package/dist/esm/effect/context.mjs +21 -6
- package/dist/esm/effect/edge-dispatcher.mjs +5 -5
- package/dist/esm/effect/edge.mjs +2 -0
- package/dist/esm/effect/entry-shape-registry.mjs +2 -2
- package/dist/esm/effect/entry-shape.mjs +27 -4
- package/dist/esm/effect/handler/batch-handler.mjs +3 -4
- package/dist/esm/effect/handler/batch.mjs +1 -7
- package/dist/esm/effect/handler/http.mjs +1 -1
- package/dist/esm/effect/handler/openapi.mjs +2 -2
- package/dist/esm/effect/handler/rpc.mjs +2 -2
- package/dist/esm/effect/handler.mjs +6 -6
- package/dist/esm/effect/index.mjs +1 -1
- package/dist/esm/effect/module.mjs +5 -1
- package/dist/esm/effect/operation-context.mjs +2 -3
- package/dist/esm/effect/rpcSerialization.mjs +1 -3
- package/dist/esm/effect-client/cross-project.mjs +8 -11
- package/dist/esm/effect-client/index.mjs +5 -5
- package/dist/esm/microvertical-api.mjs +1 -1
- package/dist/esm-node/assembly.mjs +1 -1
- package/dist/esm-node/data-platform/batch/options.mjs +11 -0
- package/dist/esm-node/data-platform/batch/queue.mjs +48 -83
- package/dist/esm-node/effect/context.mjs +21 -6
- package/dist/esm-node/effect/edge-dispatcher.mjs +5 -5
- package/dist/esm-node/effect/edge.mjs +2 -0
- package/dist/esm-node/effect/entry-shape.mjs +27 -4
- package/dist/esm-node/effect/handler/batch-handler.mjs +3 -4
- package/dist/esm-node/effect/handler/batch.mjs +1 -7
- package/dist/esm-node/effect/handler/http.mjs +1 -1
- package/dist/esm-node/effect/handler/openapi.mjs +2 -2
- package/dist/esm-node/effect/handler/rpc.mjs +2 -2
- package/dist/esm-node/effect/handler.mjs +6 -6
- package/dist/esm-node/effect/index.mjs +1 -1
- package/dist/esm-node/effect/module.mjs +5 -1
- package/dist/esm-node/effect/operation-context.mjs +2 -3
- package/dist/esm-node/effect/rpcSerialization.mjs +1 -3
- package/dist/esm-node/effect-client/cross-project.mjs +8 -11
- package/dist/esm-node/effect-client/index.mjs +5 -5
- package/dist/esm-node/microvertical-api.mjs +1 -1
- package/dist/types/assembly.d.ts +2 -2
- package/dist/types/data-platform/batch/options.d.ts +7 -0
- package/dist/types/data-platform/batch/queue.d.ts +0 -1
- package/dist/types/effect/context.d.ts +14 -1
- package/dist/types/effect/edge-dispatcher.d.ts +4 -4
- package/dist/types/effect/edge.d.ts +2 -0
- package/dist/types/effect/entry-shape.d.ts +14 -0
- package/dist/types/effect/handler/batch.d.ts +0 -1
- package/dist/types/effect/handler/definition.d.ts +2 -2
- package/dist/types/effect/handler/http.d.ts +2 -2
- package/dist/types/effect/handler/openapi.d.ts +2 -2
- package/dist/types/effect/handler/rpc.d.ts +1 -1
- package/dist/types/effect/handler/types.d.ts +5 -5
- package/dist/types/effect/handler.d.ts +5 -5
- package/dist/types/effect/module.d.ts +2 -1
- package/dist/types/effect/operation-context.d.ts +0 -1
- package/dist/types/effect/rpcSerialization.d.ts +1 -1
- package/dist/types/effect-client/cross-project.d.ts +2 -2
- package/dist/types/effect-client/index.d.ts +6 -6
- package/dist/types/microvertical-api.d.ts +4 -4
- package/package.json +39 -45
- package/src/assembly.ts +3 -2
- package/src/data-platform/batch/options.ts +20 -0
- package/src/data-platform/batch/queue.ts +61 -89
- package/src/effect/context.ts +64 -12
- package/src/effect/edge-dispatcher.ts +13 -12
- package/src/effect/edge.ts +5 -0
- package/src/effect/entry-shape.ts +97 -7
- package/src/effect/handler/batch-handler.ts +6 -12
- package/src/effect/handler/batch.ts +0 -12
- package/src/effect/handler/definition.ts +2 -3
- package/src/effect/handler/http.ts +4 -3
- package/src/effect/handler/openapi.ts +2 -2
- package/src/effect/handler/rpc.ts +3 -2
- package/src/effect/handler/types.ts +6 -12
- package/src/effect/handler.ts +5 -5
- package/src/effect/index.ts +1 -1
- package/src/effect/module.ts +8 -1
- package/src/effect/operation-context.ts +1 -5
- package/src/effect/rpcSerialization.ts +1 -3
- package/src/effect-client/cross-project.ts +11 -16
- package/src/effect-client/index.ts +11 -15
- package/src/microvertical-api.ts +1 -1
- package/dist/cjs/effect/edge-context.js +0 -61
- package/dist/esm/effect/edge-context.mjs +0 -14
- package/dist/esm-node/effect/edge-context.mjs +0 -15
- package/dist/types/effect/edge-context.d.ts +0 -5
- package/src/effect/edge-context.ts +0 -51
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
// @effect-diagnostics anyUnknownInErrorContext:off asyncFunction:off strictBooleanExpressions:off
|
|
2
|
+
|
|
3
|
+
import { runWithEffectContext } from '@modern-js/bff-effect/context';
|
|
2
4
|
import {
|
|
3
5
|
evaluateCrossProjectPolicy,
|
|
4
6
|
type NormalizedCrossProjectPolicy,
|
|
@@ -10,7 +12,6 @@ import {
|
|
|
10
12
|
type DispatchEffectBffRequestOptions,
|
|
11
13
|
dispatchEffectBffRequestWithContext,
|
|
12
14
|
} from './dispatch';
|
|
13
|
-
import { runWithEffectContext } from './edge-context';
|
|
14
15
|
import type {
|
|
15
16
|
EffectBffOpenApiConfig,
|
|
16
17
|
EffectDataPlatformValidationOptions,
|
|
@@ -22,11 +23,13 @@ import {
|
|
|
22
23
|
} from './module';
|
|
23
24
|
import type { EffectContext } from './operation-context';
|
|
24
25
|
|
|
26
|
+
export {
|
|
27
|
+
runWithEffectContext,
|
|
28
|
+
useEffectContext,
|
|
29
|
+
useOperationContext,
|
|
30
|
+
} from '@modern-js/bff-effect/context';
|
|
25
31
|
export * as Config from 'effect/Config';
|
|
26
32
|
export * as Effect from 'effect/Effect';
|
|
27
|
-
export * as Layer from 'effect/Layer';
|
|
28
|
-
export * as Option from 'effect/Option';
|
|
29
|
-
export * as Schema from 'effect/Schema';
|
|
30
33
|
export {
|
|
31
34
|
Cookies,
|
|
32
35
|
Etag,
|
|
@@ -57,7 +60,7 @@ export {
|
|
|
57
60
|
Template,
|
|
58
61
|
Url,
|
|
59
62
|
UrlParams,
|
|
60
|
-
} from 'effect/
|
|
63
|
+
} from 'effect/http';
|
|
61
64
|
export {
|
|
62
65
|
HttpApi,
|
|
63
66
|
HttpApiBuilder,
|
|
@@ -70,7 +73,9 @@ export {
|
|
|
70
73
|
HttpApiSecurity,
|
|
71
74
|
HttpApiTest,
|
|
72
75
|
OpenApi,
|
|
73
|
-
} from 'effect/
|
|
76
|
+
} from 'effect/http-api';
|
|
77
|
+
export * as Layer from 'effect/Layer';
|
|
78
|
+
export * as Option from 'effect/Option';
|
|
74
79
|
export {
|
|
75
80
|
Rpc,
|
|
76
81
|
RpcClient,
|
|
@@ -84,12 +89,8 @@ export {
|
|
|
84
89
|
RpcTest,
|
|
85
90
|
RpcWorker,
|
|
86
91
|
Utils,
|
|
87
|
-
} from 'effect/
|
|
88
|
-
export
|
|
89
|
-
runWithEffectContext,
|
|
90
|
-
useEffectContext,
|
|
91
|
-
useOperationContext,
|
|
92
|
-
} from './edge-context';
|
|
92
|
+
} from 'effect/rpc';
|
|
93
|
+
export * as Schema from 'effect/Schema';
|
|
93
94
|
export type {
|
|
94
95
|
EffectApiClientFromApi,
|
|
95
96
|
EffectBffDefinition,
|
package/src/effect/edge.ts
CHANGED
|
@@ -1,2 +1,7 @@
|
|
|
1
|
+
export { EFFECT_BFF_CONTEXT_STORAGE_SHARE } from '@modern-js/bff-effect/context';
|
|
1
2
|
export * from './edge-dispatcher';
|
|
3
|
+
export {
|
|
4
|
+
adoptEffectBffShareScope,
|
|
5
|
+
EFFECT_BFF_HANDLER_FACTORY_REGISTRY_SHARE,
|
|
6
|
+
} from './entry-shape';
|
|
2
7
|
export { createEffectBffEdgeDispatcherFactory } from './generated-entry';
|
|
@@ -1,8 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
adoptEffectContextStorage,
|
|
3
|
+
EFFECT_BFF_CONTEXT_STORAGE_SHARE,
|
|
4
|
+
} from '@modern-js/bff-effect/context';
|
|
5
|
+
import type { EffectRpcBffDefinition } from './handler/types';
|
|
6
|
+
|
|
1
7
|
type ValidatorAwareHandlerFactoryRegistry = {
|
|
2
8
|
register<TFactory extends Function>(factory: TFactory): TFactory;
|
|
3
9
|
is(factory: unknown): boolean;
|
|
4
10
|
};
|
|
5
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Module Federation share through which a backend federation host hands its
|
|
14
|
+
* package-private handler factory registry to the containers it initializes.
|
|
15
|
+
*/
|
|
16
|
+
export const EFFECT_BFF_HANDLER_FACTORY_REGISTRY_SHARE =
|
|
17
|
+
'@modern-js/bff-effect/handler-factory-registry';
|
|
18
|
+
|
|
6
19
|
function createLocalValidatorAwareHandlerFactoryRegistry(): ValidatorAwareHandlerFactoryRegistry {
|
|
7
20
|
const factories = new WeakSet<Function>();
|
|
8
21
|
return {
|
|
@@ -19,6 +32,8 @@ function createLocalValidatorAwareHandlerFactoryRegistry(): ValidatorAwareHandle
|
|
|
19
32
|
function loadNodeValidatorAwareHandlerFactoryRegistry(): ValidatorAwareHandlerFactoryRegistry {
|
|
20
33
|
const moduleUrl = import.meta.url;
|
|
21
34
|
if (typeof moduleUrl !== 'string' || !moduleUrl.startsWith('file:')) {
|
|
35
|
+
// A bundled backend federation container has no file URL; its host share
|
|
36
|
+
// arrives through adoptEffectBffShareScope() during container init.
|
|
22
37
|
return createLocalValidatorAwareHandlerFactoryRegistry();
|
|
23
38
|
}
|
|
24
39
|
|
|
@@ -44,15 +59,90 @@ function loadNodeValidatorAwareHandlerFactoryRegistry(): ValidatorAwareHandlerFa
|
|
|
44
59
|
|
|
45
60
|
declare const __MODERN_EFFECT_NODE_RUNTIME__: boolean;
|
|
46
61
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
62
|
+
let validatorAwareHandlerFactoryRegistry:
|
|
63
|
+
| ValidatorAwareHandlerFactoryRegistry
|
|
64
|
+
| undefined;
|
|
65
|
+
|
|
66
|
+
function handlerFactoryRegistry(): ValidatorAwareHandlerFactoryRegistry {
|
|
67
|
+
validatorAwareHandlerFactoryRegistry ??=
|
|
68
|
+
typeof __MODERN_EFFECT_NODE_RUNTIME__ !== 'undefined' &&
|
|
69
|
+
__MODERN_EFFECT_NODE_RUNTIME__
|
|
70
|
+
? loadNodeValidatorAwareHandlerFactoryRegistry()
|
|
71
|
+
: createLocalValidatorAwareHandlerFactoryRegistry();
|
|
72
|
+
return validatorAwareHandlerFactoryRegistry;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
type SharedVersions = Record<string, { get?: () => unknown } | undefined>;
|
|
76
|
+
|
|
77
|
+
const adoptShared = (
|
|
78
|
+
shareScope: unknown,
|
|
79
|
+
name: string,
|
|
80
|
+
adopt: (value: unknown) => void,
|
|
81
|
+
): Promise<void> => {
|
|
82
|
+
const versions =
|
|
83
|
+
typeof shareScope === 'object' && shareScope !== null
|
|
84
|
+
? (shareScope as Record<string, SharedVersions | undefined>)[name]
|
|
85
|
+
: undefined;
|
|
86
|
+
const shared =
|
|
87
|
+
versions === undefined ? undefined : Object.values(versions)[0];
|
|
88
|
+
if (typeof shared?.get !== 'function') {
|
|
89
|
+
return Promise.resolve();
|
|
90
|
+
}
|
|
91
|
+
return Promise.resolve(shared.get()).then(factory =>
|
|
92
|
+
adopt(typeof factory === 'function' ? factory() : undefined),
|
|
93
|
+
);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @internal Called by generated backend federation containers from `init()`,
|
|
98
|
+
* before any expose evaluates, so factories created by `defineEffectBff`
|
|
99
|
+
* register with the host's registry and endpoints read the host's request
|
|
100
|
+
* storage instead of bundle-local ones.
|
|
101
|
+
*/
|
|
102
|
+
export function adoptEffectBffShareScope(shareScope: unknown): Promise<void> {
|
|
103
|
+
return Promise.all([
|
|
104
|
+
adoptShared(
|
|
105
|
+
shareScope,
|
|
106
|
+
EFFECT_BFF_HANDLER_FACTORY_REGISTRY_SHARE,
|
|
107
|
+
registry =>
|
|
108
|
+
adoptHandlerFactoryRegistry(
|
|
109
|
+
registry as ValidatorAwareHandlerFactoryRegistry | undefined,
|
|
110
|
+
),
|
|
111
|
+
),
|
|
112
|
+
adoptShared(
|
|
113
|
+
shareScope,
|
|
114
|
+
EFFECT_BFF_CONTEXT_STORAGE_SHARE,
|
|
115
|
+
adoptEffectContextStorage,
|
|
116
|
+
),
|
|
117
|
+
]).then(() => undefined);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function adoptHandlerFactoryRegistry(
|
|
121
|
+
registry: ValidatorAwareHandlerFactoryRegistry | undefined,
|
|
122
|
+
): void {
|
|
123
|
+
if (
|
|
124
|
+
typeof registry?.register !== 'function' ||
|
|
125
|
+
typeof registry.is !== 'function'
|
|
126
|
+
) {
|
|
127
|
+
throw new Error(
|
|
128
|
+
`[BFF][Effect] Share ${EFFECT_BFF_HANDLER_FACTORY_REGISTRY_SHARE} must provide a handler factory registry.`,
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
if (
|
|
132
|
+
validatorAwareHandlerFactoryRegistry !== undefined &&
|
|
133
|
+
validatorAwareHandlerFactoryRegistry !== registry
|
|
134
|
+
) {
|
|
135
|
+
throw new Error(
|
|
136
|
+
'[BFF][Effect] A backend federation container received the host handler factory registry after an Effect API already used its own. Evaluate exposes only after container init().',
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
validatorAwareHandlerFactoryRegistry = registry;
|
|
140
|
+
}
|
|
52
141
|
|
|
53
142
|
type EffectBffEntryModule = {
|
|
54
143
|
api?: unknown;
|
|
55
144
|
layer?: unknown;
|
|
145
|
+
rpc?: EffectRpcBffDefinition;
|
|
56
146
|
handler?: unknown;
|
|
57
147
|
createHandler?: unknown;
|
|
58
148
|
default?: unknown;
|
|
@@ -82,7 +172,7 @@ type EffectBffEntryShapePredicates = {
|
|
|
82
172
|
export function registerValidatorAwareHandlerFactory<TFactory extends Function>(
|
|
83
173
|
factory: TFactory,
|
|
84
174
|
): TFactory {
|
|
85
|
-
return
|
|
175
|
+
return handlerFactoryRegistry().register(factory);
|
|
86
176
|
}
|
|
87
177
|
|
|
88
178
|
/**
|
|
@@ -90,7 +180,7 @@ export function registerValidatorAwareHandlerFactory<TFactory extends Function>(
|
|
|
90
180
|
* therefore forwards strict cross-project validation into createHttpApiHandler.
|
|
91
181
|
*/
|
|
92
182
|
export function isValidatorAwareHandlerFactory(factory: unknown): boolean {
|
|
93
|
-
return
|
|
183
|
+
return handlerFactoryRegistry().is(factory);
|
|
94
184
|
}
|
|
95
185
|
|
|
96
186
|
export const strictEffectApproachMessage =
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
isPlainObject,
|
|
9
9
|
normalizeMethod as normalizeItemMethod,
|
|
10
10
|
} from '../../data-platform';
|
|
11
|
+
import { normalizeBatchLimits } from '../../data-platform/batch/options';
|
|
11
12
|
import {
|
|
12
13
|
decodeBatchBody,
|
|
13
14
|
isBatchBody,
|
|
@@ -18,7 +19,6 @@ import {
|
|
|
18
19
|
createBatchValidationResponse,
|
|
19
20
|
isBatchRequestPayload,
|
|
20
21
|
mapWithConcurrency,
|
|
21
|
-
normalizeBatchAllowedMethods,
|
|
22
22
|
normalizeBatchPath,
|
|
23
23
|
promiseWithTimeout,
|
|
24
24
|
toBatchItemError,
|
|
@@ -129,14 +129,11 @@ export function createDataPlatformBatchRequestHandler<TContext>(options: {
|
|
|
129
129
|
const dataPlatformBatchOptions = options.dataPlatform?.batch;
|
|
130
130
|
const batchEnabled = dataPlatformBatchOptions?.enabled !== false;
|
|
131
131
|
const batchPath = normalizeBatchPath(dataPlatformBatchOptions?.endpoint);
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
1024,
|
|
138
|
-
dataPlatformBatchOptions?.maxBatchBytes ?? 64 * 1024,
|
|
139
|
-
);
|
|
132
|
+
const {
|
|
133
|
+
maxBatchSize: batchMaxSize,
|
|
134
|
+
maxBatchBytes: batchMaxBytes,
|
|
135
|
+
allowedMethods: batchAllowedMethods,
|
|
136
|
+
} = normalizeBatchLimits(dataPlatformBatchOptions);
|
|
140
137
|
const batchConcurrency = Math.max(
|
|
141
138
|
1,
|
|
142
139
|
dataPlatformBatchOptions?.maxConcurrency ?? 4,
|
|
@@ -145,9 +142,6 @@ export function createDataPlatformBatchRequestHandler<TContext>(options: {
|
|
|
145
142
|
0,
|
|
146
143
|
dataPlatformBatchOptions?.requestTimeoutMs ?? 10_000,
|
|
147
144
|
);
|
|
148
|
-
const batchAllowedMethods = normalizeBatchAllowedMethods(
|
|
149
|
-
dataPlatformBatchOptions?.allowedMethods,
|
|
150
|
-
);
|
|
151
145
|
const envelopeHeader =
|
|
152
146
|
options.dataPlatform?.envelopeHeader || DEFAULT_DATA_ENVELOPE_HEADER;
|
|
153
147
|
const normalizedEnvelopeHeader = envelopeHeader.toLowerCase();
|
|
@@ -6,11 +6,9 @@ import {
|
|
|
6
6
|
type DataBatchResponseItem,
|
|
7
7
|
DEFAULT_DATA_BATCH_ENDPOINT,
|
|
8
8
|
isPlainObject,
|
|
9
|
-
measureTextBytes,
|
|
10
9
|
normalizeMethod as normalizeItemMethod,
|
|
11
10
|
} from '../../data-platform';
|
|
12
11
|
import { encodeBatchText } from '../../data-platform/batch/protocol';
|
|
13
|
-
import { toHeaderRecord } from '../../headers';
|
|
14
12
|
|
|
15
13
|
export { toHeaderRecord } from '../../headers';
|
|
16
14
|
|
|
@@ -24,16 +22,6 @@ export function normalizeBatchPath(pathname: string | undefined) {
|
|
|
24
22
|
return pathname as `/${string}`;
|
|
25
23
|
}
|
|
26
24
|
|
|
27
|
-
export function normalizeBatchAllowedMethods(
|
|
28
|
-
allowedMethods: string[] | undefined,
|
|
29
|
-
) {
|
|
30
|
-
const source =
|
|
31
|
-
Array.isArray(allowedMethods) && allowedMethods.length > 0
|
|
32
|
-
? allowedMethods
|
|
33
|
-
: ['GET'];
|
|
34
|
-
return new Set(source.map(method => method.toUpperCase()));
|
|
35
|
-
}
|
|
36
|
-
|
|
37
25
|
type ParsedBatchRequestPayload = Omit<DataBatchRequestPayload, 'items'> & {
|
|
38
26
|
items: unknown[];
|
|
39
27
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @effect-diagnostics anyUnknownInErrorContext:off asyncFunction:off globalDate:off globalTimers:off newPromise:off strictBooleanExpressions:off
|
|
2
|
-
import type { HttpApi } from 'effect/
|
|
3
|
-
import type { Rpc } from 'effect/
|
|
2
|
+
import type { HttpApi } from 'effect/http-api';
|
|
3
|
+
import type { Rpc } from 'effect/rpc';
|
|
4
4
|
|
|
5
5
|
import { registerValidatorAwareHandlerFactory } from '../entry-shape';
|
|
6
6
|
import { mergeDataPlatformOptions } from './envelope';
|
|
@@ -10,7 +10,6 @@ import type {
|
|
|
10
10
|
EffectBffDefinition,
|
|
11
11
|
EffectBffHandlerFactory,
|
|
12
12
|
EffectBffRuntime,
|
|
13
|
-
EffectDataPlatformValidationOptions,
|
|
14
13
|
EffectRpcBffDefinition,
|
|
15
14
|
EffectRpcBffHandlerFactory,
|
|
16
15
|
EffectRpcRuntimeLayer,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// @effect-diagnostics anyUnknownInErrorContext:off asyncFunction:off globalDate:off globalTimers:off newPromise:off strictBooleanExpressions:off
|
|
2
|
+
|
|
3
|
+
import { HttpRouter, HttpServer } from 'effect/http';
|
|
4
|
+
import type { HttpApi } from 'effect/http-api';
|
|
2
5
|
import * as Layer from 'effect/Layer';
|
|
3
|
-
import {
|
|
4
|
-
import type { HttpApi } from 'effect/unstable/httpapi';
|
|
5
|
-
import type { Rpc } from 'effect/unstable/rpc';
|
|
6
|
+
import type { Rpc } from 'effect/rpc';
|
|
6
7
|
|
|
7
8
|
import { prepareJsonRequestBody } from './batch';
|
|
8
9
|
import { createDataPlatformBatchRequestHandler } from './batch-handler';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @effect-diagnostics anyUnknownInErrorContext:off asyncFunction:off globalDate:off globalTimers:off newPromise:off strictBooleanExpressions:off
|
|
2
|
-
import { HttpRouter, HttpServerResponse } from 'effect/
|
|
3
|
-
import { type HttpApi, OpenApi } from 'effect/
|
|
2
|
+
import { HttpRouter, HttpServerResponse } from 'effect/http';
|
|
3
|
+
import { type HttpApi, OpenApi } from 'effect/http-api';
|
|
4
4
|
|
|
5
5
|
import type { EffectBffOpenApiConfig } from './types';
|
|
6
6
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// @effect-diagnostics anyUnknownInErrorContext:off asyncFunction:off globalDate:off globalTimers:off newPromise:off strictBooleanExpressions:off
|
|
2
|
+
|
|
3
|
+
import { HttpRouter } from 'effect/http';
|
|
2
4
|
import * as Layer from 'effect/Layer';
|
|
3
|
-
import {
|
|
4
|
-
import { type Rpc, RpcServer } from 'effect/unstable/rpc';
|
|
5
|
+
import { type Rpc, RpcServer } from 'effect/rpc';
|
|
5
6
|
|
|
6
7
|
import { getRpcSerializationLayer } from '../rpcSerialization';
|
|
7
8
|
import type { EffectRpcBffDefinition } from './types';
|
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
// @effect-diagnostics anyUnknownInErrorContext:off asyncFunction:off globalDate:off globalTimers:off newPromise:off strictBooleanExpressions:off
|
|
2
2
|
import type { FileSystem, Path } from 'effect';
|
|
3
3
|
import * as Context from 'effect/Context';
|
|
4
|
-
import type
|
|
4
|
+
import type { Etag, HttpPlatform, HttpRouter } from 'effect/http';
|
|
5
|
+
import type { HttpApi, HttpApiClient, HttpApiGroup } from 'effect/http-api';
|
|
5
6
|
import type * as Layer from 'effect/Layer';
|
|
6
|
-
import type {
|
|
7
|
-
import type {
|
|
8
|
-
HttpApi,
|
|
9
|
-
HttpApiClient,
|
|
10
|
-
HttpApiGroup,
|
|
11
|
-
} from 'effect/unstable/httpapi';
|
|
12
|
-
import type { Rpc, RpcGroup } from 'effect/unstable/rpc';
|
|
7
|
+
import type { Rpc, RpcGroup } from 'effect/rpc';
|
|
13
8
|
|
|
14
9
|
import type { createHttpApiHandler } from './http';
|
|
15
10
|
import type { createRpcApiHandler } from './rpc';
|
|
@@ -43,8 +38,7 @@ export type EffectRpcSerialization =
|
|
|
43
38
|
| 'json'
|
|
44
39
|
| 'ndjson'
|
|
45
40
|
| 'jsonRpc'
|
|
46
|
-
| 'ndJsonRpc'
|
|
47
|
-
| 'msgPack';
|
|
41
|
+
| 'ndJsonRpc';
|
|
48
42
|
|
|
49
43
|
export type EffectRpcRuntimeLayer<TRpcs extends Rpc.Any = Rpc.Any> =
|
|
50
44
|
Layer.Layer<
|
|
@@ -201,8 +195,8 @@ export type EffectRequestInterceptor = (options: {
|
|
|
201
195
|
}) => Response | Promise<Response>;
|
|
202
196
|
|
|
203
197
|
export type EffectBffHandlerFactory<
|
|
204
|
-
|
|
205
|
-
|
|
198
|
+
_TApi extends HttpApi.Constraint = HttpApi.Top,
|
|
199
|
+
_TLayer extends EffectRuntimeLayer = EffectRuntimeLayer,
|
|
206
200
|
> = (options?: {
|
|
207
201
|
openapi?: EffectBffOpenApiConfig;
|
|
208
202
|
rpc?: Partial<EffectRpcBffHandlerOptions>;
|
package/src/effect/handler.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
// @effect-diagnostics anyUnknownInErrorContext:off asyncFunction:off globalDate:off globalTimers:off newPromise:off strictBooleanExpressions:off
|
|
2
2
|
export * as Config from 'effect/Config';
|
|
3
3
|
export * as Effect from 'effect/Effect';
|
|
4
|
+
export * from 'effect/http';
|
|
5
|
+
export { HttpTraceContext } from 'effect/http';
|
|
6
|
+
export * from 'effect/http-api';
|
|
7
|
+
export { HttpApiBuilder } from 'effect/http-api';
|
|
4
8
|
export * as Layer from 'effect/Layer';
|
|
5
9
|
export * as Option from 'effect/Option';
|
|
10
|
+
export * from 'effect/rpc';
|
|
6
11
|
export * as Schema from 'effect/Schema';
|
|
7
|
-
export * from 'effect/unstable/http';
|
|
8
|
-
export { HttpTraceContext } from 'effect/unstable/http';
|
|
9
|
-
export * from 'effect/unstable/httpapi';
|
|
10
|
-
export { HttpApiBuilder } from 'effect/unstable/httpapi';
|
|
11
|
-
export * from 'effect/unstable/rpc';
|
|
12
12
|
|
|
13
13
|
export { defineEffectBff, defineEffectRpcBff } from './handler/definition';
|
|
14
14
|
export { createHttpApiHandler } from './handler/http';
|
package/src/effect/index.ts
CHANGED
package/src/effect/module.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @effect-diagnostics strictBooleanExpressions:off
|
|
2
2
|
import type * as EffectServiceContext from 'effect/Context';
|
|
3
|
-
import { HttpApi } from 'effect/
|
|
3
|
+
import { HttpApi } from 'effect/http-api';
|
|
4
4
|
import {
|
|
5
5
|
classifyEffectBffEntryModule,
|
|
6
6
|
type EffectBffEntryShapeFacts,
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
type EffectBffOpenApiConfig,
|
|
13
13
|
type EffectDataPlatformValidationOptions,
|
|
14
14
|
type EffectRequestValidator,
|
|
15
|
+
type EffectRpcBffDefinition,
|
|
15
16
|
type EffectRuntimeLayer,
|
|
16
17
|
} from './handler';
|
|
17
18
|
import type { EffectContext } from './operation-context';
|
|
@@ -33,6 +34,7 @@ export type EffectBffHandlerFactory = (options?: {
|
|
|
33
34
|
export type EffectApiModule = {
|
|
34
35
|
api?: unknown;
|
|
35
36
|
layer?: unknown;
|
|
37
|
+
rpc?: EffectRpcBffDefinition;
|
|
36
38
|
handler?: EffectBffRequestHandler;
|
|
37
39
|
createHandler?: EffectBffHandlerFactory;
|
|
38
40
|
default?: unknown;
|
|
@@ -125,6 +127,11 @@ function resolveClassifiedEffectBffModuleHandler(
|
|
|
125
127
|
}
|
|
126
128
|
}
|
|
127
129
|
|
|
130
|
+
if (facts.module.rpc !== undefined && !facts.createHandlerValidatorAware) {
|
|
131
|
+
rejectUnsupportedEffectModuleShape(options, 'unbranded RPC runtime');
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
|
|
128
135
|
if (typeof facts.createHandler === 'function') {
|
|
129
136
|
if (facts.createHandlerValidatorAware) {
|
|
130
137
|
const factory = facts.createHandler as EffectBffHandlerFactory;
|
|
@@ -21,10 +21,6 @@ export type EffectContextStorage = {
|
|
|
21
21
|
run: <TResult>(value: EffectContext, cb: () => TResult) => TResult;
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
export const kEffectContextStorage = Symbol.for(
|
|
25
|
-
'modernjs.plugin-bff.effectContextStorage',
|
|
26
|
-
);
|
|
27
|
-
|
|
28
24
|
export type CreateEffectOperationContextOptions = Omit<
|
|
29
25
|
EffectContext,
|
|
30
26
|
'operationContext'
|
|
@@ -128,7 +124,7 @@ export const createEffectOperationContext = ({
|
|
|
128
124
|
: {}),
|
|
129
125
|
routePath: servicePath,
|
|
130
126
|
method: (method || request.method || 'GET').toUpperCase(),
|
|
131
|
-
source: 'effect-
|
|
127
|
+
source: 'effect-server',
|
|
132
128
|
...(path && path !== servicePath
|
|
133
129
|
? { attributes: { mountedPath: path } }
|
|
134
130
|
: {}),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RpcSerialization } from 'effect/
|
|
1
|
+
import { RpcSerialization } from 'effect/rpc';
|
|
2
2
|
|
|
3
3
|
import type { EffectRpcSerialization } from './handler/types';
|
|
4
4
|
|
|
@@ -12,8 +12,6 @@ export function getRpcSerializationLayer(
|
|
|
12
12
|
return RpcSerialization.layerJsonRpc();
|
|
13
13
|
case 'ndJsonRpc':
|
|
14
14
|
return RpcSerialization.layerNdJsonRpc();
|
|
15
|
-
case 'msgPack':
|
|
16
|
-
return RpcSerialization.layerMsgPack;
|
|
17
15
|
default:
|
|
18
16
|
return RpcSerialization.layerJsonRpc();
|
|
19
17
|
}
|
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
BFF_ENVELOPE_HEADER,
|
|
3
3
|
BFF_OPERATION_CONTEXT_DETAIL_HEADER,
|
|
4
4
|
BFF_OPERATION_CONTEXT_HEADER,
|
|
5
|
+
digestOperationContract,
|
|
5
6
|
resolveCrossProjectRequestObservation,
|
|
6
7
|
} from '@modern-js/server-runtime-extensions/bff-policy';
|
|
7
8
|
import * as Effect from 'effect/Effect';
|
|
@@ -9,8 +10,8 @@ import * as Schema from 'effect/Schema';
|
|
|
9
10
|
|
|
10
11
|
const encodeJson = Schema.encodeSync(Schema.fromJsonString(Schema.Unknown));
|
|
11
12
|
|
|
12
|
-
import { HttpClient, HttpClientRequest } from 'effect/
|
|
13
|
-
import { HttpApi, type HttpApiGroup } from 'effect/
|
|
13
|
+
import { HttpClient, HttpClientRequest } from 'effect/http';
|
|
14
|
+
import { HttpApi, type HttpApiGroup } from 'effect/http-api';
|
|
14
15
|
|
|
15
16
|
export interface EffectCrossProjectClientOptions {
|
|
16
17
|
requestId: string;
|
|
@@ -66,22 +67,16 @@ export function withCrossProjectPolicy<
|
|
|
66
67
|
);
|
|
67
68
|
}
|
|
68
69
|
return Effect.gen(function* () {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
globalThis.crypto.subtle.digest(
|
|
78
|
-
'SHA-256',
|
|
79
|
-
new TextEncoder().encode(input),
|
|
70
|
+
const schemaHash = yield* Effect.promise(() =>
|
|
71
|
+
digestOperationContract(
|
|
72
|
+
{
|
|
73
|
+
httpMethod: contract.method,
|
|
74
|
+
name: contract.name,
|
|
75
|
+
routePath: contract.routePath,
|
|
76
|
+
},
|
|
77
|
+
options.requestId,
|
|
80
78
|
),
|
|
81
79
|
);
|
|
82
|
-
const schemaHash = Array.from(new Uint8Array(digest), value =>
|
|
83
|
-
value.toString(16).padStart(2, '0'),
|
|
84
|
-
).join('');
|
|
85
80
|
return request.pipe(
|
|
86
81
|
HttpClientRequest.setHeader(
|
|
87
82
|
BFF_ENVELOPE_HEADER,
|
|
@@ -6,28 +6,25 @@ import {
|
|
|
6
6
|
import * as Data from 'effect/Data';
|
|
7
7
|
import * as Effect from 'effect/Effect';
|
|
8
8
|
import * as Exit from 'effect/Exit';
|
|
9
|
-
import
|
|
10
|
-
import * as ManagedRuntime from 'effect/ManagedRuntime';
|
|
11
|
-
import * as Scope from 'effect/Scope';
|
|
12
|
-
import {
|
|
13
|
-
FetchHttpClient,
|
|
14
|
-
HttpClient,
|
|
15
|
-
HttpClientRequest,
|
|
16
|
-
} from 'effect/unstable/http';
|
|
9
|
+
import { FetchHttpClient, HttpClient, HttpClientRequest } from 'effect/http';
|
|
17
10
|
import {
|
|
18
11
|
HttpApi,
|
|
19
12
|
HttpApiClient,
|
|
20
13
|
HttpApiEndpoint,
|
|
21
14
|
HttpApiGroup,
|
|
22
15
|
HttpApiSchema,
|
|
23
|
-
} from 'effect/
|
|
16
|
+
} from 'effect/http-api';
|
|
17
|
+
import * as Layer from 'effect/Layer';
|
|
18
|
+
import * as ManagedRuntime from 'effect/ManagedRuntime';
|
|
24
19
|
import {
|
|
25
20
|
Rpc,
|
|
26
21
|
RpcClient,
|
|
22
|
+
RpcClientError,
|
|
27
23
|
RpcGroup,
|
|
28
24
|
RpcSchema,
|
|
29
25
|
RpcSerialization,
|
|
30
|
-
} from 'effect/
|
|
26
|
+
} from 'effect/rpc';
|
|
27
|
+
import * as Scope from 'effect/Scope';
|
|
31
28
|
|
|
32
29
|
import { getRpcSerializationLayer } from '../effect/rpcSerialization';
|
|
33
30
|
import {
|
|
@@ -36,9 +33,9 @@ import {
|
|
|
36
33
|
} from './cross-project';
|
|
37
34
|
|
|
38
35
|
export * as Effect from 'effect/Effect';
|
|
36
|
+
export * as HttpClientError from 'effect/http/HttpClientError';
|
|
39
37
|
export * as Layer from 'effect/Layer';
|
|
40
38
|
export * as Schema from 'effect/Schema';
|
|
41
|
-
export * as HttpClientError from 'effect/unstable/http/HttpClientError';
|
|
42
39
|
export type { EffectCrossProjectClientOptions } from './cross-project';
|
|
43
40
|
export {
|
|
44
41
|
HttpApi,
|
|
@@ -106,8 +103,7 @@ export type EffectRpcSerialization =
|
|
|
106
103
|
| 'json'
|
|
107
104
|
| 'ndjson'
|
|
108
105
|
| 'jsonRpc'
|
|
109
|
-
| 'ndJsonRpc'
|
|
110
|
-
| 'msgPack';
|
|
106
|
+
| 'ndJsonRpc';
|
|
111
107
|
|
|
112
108
|
export class EffectRpcClientError extends Data.TaggedError(
|
|
113
109
|
'EffectRpcClientError',
|
|
@@ -138,8 +134,8 @@ export type EffectRpcClientHandle<
|
|
|
138
134
|
Rpcs extends Rpc.Any,
|
|
139
135
|
Flatten extends boolean = false,
|
|
140
136
|
> = (Flatten extends true
|
|
141
|
-
? RpcClient.RpcClient.Flat<Rpcs,
|
|
142
|
-
: RpcClient.RpcClient<Rpcs,
|
|
137
|
+
? RpcClient.RpcClient.Flat<Rpcs, RpcClientError.RpcClientError>
|
|
138
|
+
: RpcClient.RpcClient<Rpcs, RpcClientError.RpcClientError>) & {
|
|
143
139
|
dispose: () => Promise<void>;
|
|
144
140
|
};
|
|
145
141
|
|