@bleedingdev/modern-js-plugin 3.9.0-ultramodern.4 → 3.9.0-ultramodern.6

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.
@@ -74,7 +74,9 @@ function initPluginAPI({ context, plugins }) {
74
74
  config: hooks.config.tap,
75
75
  onBeforeRender: hooks.onBeforeRender.tap,
76
76
  wrapRoot: hooks.wrapRoot.tap,
77
+ resolveComponent: hooks.resolveComponent.tap,
77
78
  pickContext: hooks.pickContext.tap,
79
+ transformRuntimeContext: hooks.transformRuntimeContext.tap,
78
80
  extendStringSSRCollectors: hooks.extendStringSSRCollectors.tap,
79
81
  extendStreamSSR: hooks.extendStreamSSR.tap,
80
82
  ...extendsPluginApi
@@ -35,7 +35,9 @@ function initHooks() {
35
35
  return {
36
36
  onBeforeRender: (0, external_hooks_js_namespaceObject.createAsyncInterruptHook)(),
37
37
  wrapRoot: (0, external_hooks_js_namespaceObject.createSyncHook)(),
38
+ resolveComponent: (0, external_hooks_js_namespaceObject.createSyncHook)(),
38
39
  pickContext: (0, external_hooks_js_namespaceObject.createSyncHook)(),
40
+ transformRuntimeContext: (0, external_hooks_js_namespaceObject.createSyncHook)(),
39
41
  config: (0, external_hooks_js_namespaceObject.createCollectSyncHook)(),
40
42
  extendStringSSRCollectors: (0, external_hooks_js_namespaceObject.createCollectSyncHook)(),
41
43
  extendStreamSSR: (0, external_hooks_js_namespaceObject.createCollectSyncHook)()
@@ -42,7 +42,9 @@ function initPluginAPI({ context, plugins }) {
42
42
  config: hooks.config.tap,
43
43
  onBeforeRender: hooks.onBeforeRender.tap,
44
44
  wrapRoot: hooks.wrapRoot.tap,
45
+ resolveComponent: hooks.resolveComponent.tap,
45
46
  pickContext: hooks.pickContext.tap,
47
+ transformRuntimeContext: hooks.transformRuntimeContext.tap,
46
48
  extendStringSSRCollectors: hooks.extendStringSSRCollectors.tap,
47
49
  extendStreamSSR: hooks.extendStreamSSR.tap,
48
50
  ...extendsPluginApi
@@ -3,7 +3,9 @@ function initHooks() {
3
3
  return {
4
4
  onBeforeRender: createAsyncInterruptHook(),
5
5
  wrapRoot: createSyncHook(),
6
+ resolveComponent: createSyncHook(),
6
7
  pickContext: createSyncHook(),
8
+ transformRuntimeContext: createSyncHook(),
7
9
  config: createCollectSyncHook(),
8
10
  extendStringSSRCollectors: createCollectSyncHook(),
9
11
  extendStreamSSR: createCollectSyncHook()
@@ -43,7 +43,9 @@ function initPluginAPI({ context, plugins }) {
43
43
  config: hooks.config.tap,
44
44
  onBeforeRender: hooks.onBeforeRender.tap,
45
45
  wrapRoot: hooks.wrapRoot.tap,
46
+ resolveComponent: hooks.resolveComponent.tap,
46
47
  pickContext: hooks.pickContext.tap,
48
+ transformRuntimeContext: hooks.transformRuntimeContext.tap,
47
49
  extendStringSSRCollectors: hooks.extendStringSSRCollectors.tap,
48
50
  extendStreamSSR: hooks.extendStreamSSR.tap,
49
51
  ...extendsPluginApi
@@ -4,7 +4,9 @@ function initHooks() {
4
4
  return {
5
5
  onBeforeRender: createAsyncInterruptHook(),
6
6
  wrapRoot: createSyncHook(),
7
+ resolveComponent: createSyncHook(),
7
8
  pickContext: createSyncHook(),
9
+ transformRuntimeContext: createSyncHook(),
8
10
  config: createCollectSyncHook(),
9
11
  extendStringSSRCollectors: createCollectSyncHook(),
10
12
  extendStreamSSR: createCollectSyncHook()
@@ -1,4 +1,5 @@
1
1
  export type { Hooks, InternalRuntimeContext, RuntimeContext, RuntimePlugin, RuntimePluginAPI, RuntimePluginExtends, } from '../types/runtime/index.js';
2
+ export type { Collector, ExtendStreamSSRFn, ResolveComponentFn, RuntimeContextProjection, SSRAssetGroup, SSRAssetTransformInfo, SSRHeadData, SSRHeadPart, SSRHtmlFormatting, SSRRenderAsset, SSRRenderInfo, SSRRenderLifecycle, SSRRenderTerminal, SSRRouterData, SSRTemplateChunk, StreamSSRExtender, StreamSSRInfo, StringSSRCollectorsInfo, TransformRuntimeContextFn, } from '../types/runtime/hooks.js';
2
3
  export { initPluginAPI } from './api.js';
3
4
  export { createRuntimeContext, initRuntimeContext } from './context.js';
4
5
  export { initHooks } from './hooks.js';
@@ -2,3 +2,4 @@ export { initPluginAPI } from './api.js';
2
2
  export { createServerContext, initServerContext } from './context.js';
3
3
  export { type Hooks, initHooks, type ModifyConfigFn, type OnPrepareFn, type OnResetFn, } from './hooks.js';
4
4
  export { createServer, type ServerCreateOptions, server } from './run/index.js';
5
+ export type { BffRuntimeFramework, BffRuntimeRegistry } from './run/types.js';
@@ -1,5 +1,10 @@
1
1
  import type { ServerRoute } from '@modern-js/types';
2
2
  import type { Plugin } from '../../types/plugin.js';
3
+ /** Registered BFF runtimes. Runtime packages extend this interface. */
4
+ export interface BffRuntimeRegistry {
5
+ hono: true;
6
+ }
7
+ export type BffRuntimeFramework = keyof BffRuntimeRegistry;
3
8
  export type ServerCreateOptions = {
4
9
  /** server working directory, and then also dist directory */
5
10
  pwd: string;
@@ -11,7 +16,7 @@ export type ServerCreateOptions = {
11
16
  sharedDirectory?: string;
12
17
  apiDirectory?: string;
13
18
  lambdaDirectory?: string;
14
- bffRuntimeFramework?: 'hono' | 'effect';
19
+ bffRuntimeFramework?: BffRuntimeFramework;
15
20
  };
16
21
  };
17
22
  export type ServerRunOptions = {
@@ -1,7 +1,7 @@
1
1
  import type { PluginHook, PluginHookTap } from '../hooks.js';
2
2
  import type { DeepPartial } from '../utils.js';
3
3
  import type { RuntimeContext } from './context.js';
4
- import type { ConfigFn, ExtendStreamSSRFn, ExtendStringSSRCollectorsFn, Hooks, OnBeforeRenderFn, PickContextFn, StringSSRCollectorsInfo, WrapRootFn } from './hooks.js';
4
+ import type { ConfigFn, ExtendStreamSSRFn, ExtendStringSSRCollectorsFn, Hooks, OnBeforeRenderFn, PickContextFn, ResolveComponentFn, StringSSRCollectorsInfo, TransformRuntimeContextFn, WrapRootFn } from './hooks.js';
5
5
  import type { RuntimePluginExtends } from './plugin.js';
6
6
  export type RuntimePluginAPI<Extends extends RuntimePluginExtends> = Readonly<{
7
7
  updateRuntimeContext: (updateContext: DeepPartial<RuntimeContext>) => void;
@@ -9,10 +9,12 @@ export type RuntimePluginAPI<Extends extends RuntimePluginExtends> = Readonly<{
9
9
  getRuntimeConfig: () => Readonly<Extends['config']>;
10
10
  onBeforeRender: PluginHookTap<OnBeforeRenderFn<Extends['extendContext']>>;
11
11
  wrapRoot: PluginHookTap<WrapRootFn>;
12
+ resolveComponent: PluginHookTap<ResolveComponentFn>;
12
13
  pickContext: PluginHookTap<PickContextFn<RuntimeContext>>;
14
+ transformRuntimeContext: PluginHookTap<TransformRuntimeContextFn<RuntimeContext & Extends['extendContext']>>;
13
15
  config: PluginHookTap<ConfigFn<Extends['config']>>;
14
- extendStringSSRCollectors: PluginHookTap<ExtendStringSSRCollectorsFn<StringSSRCollectorsInfo>>;
15
- extendStreamSSR: PluginHookTap<ExtendStreamSSRFn>;
16
+ extendStringSSRCollectors: PluginHookTap<ExtendStringSSRCollectorsFn<StringSSRCollectorsInfo<RuntimeContext & Extends['extendContext']>>>;
17
+ extendStreamSSR: PluginHookTap<ExtendStreamSSRFn<RuntimeContext & Extends['extendContext']>>;
16
18
  } & RuntimePluginExtendsAPI<Extends>>;
17
19
  export type RuntimePluginExtendsAPI<Extends extends RuntimePluginExtends> = {
18
20
  [K in keyof Extends['extendHooks']]: PluginHookTap<Extends['extendHooks'][K] extends PluginHook<infer Args> ? Args extends (...args: any[]) => any ? Args : (...args: any[]) => any : (...args: any[]) => any>;
@@ -5,7 +5,83 @@ export type ChunkSet = {
5
5
  jsChunk: string;
6
6
  cssChunk: string;
7
7
  };
8
- export type Collector = {
8
+ export type SSRRenderInfo<RuntimeContext = object> = {
9
+ /** The original request context, before public or RSC projection. */
10
+ runtimeContext: RuntimeContext;
11
+ request: Request;
12
+ platform: 'node' | 'web';
13
+ mode: 'string' | 'stream';
14
+ isRsc: boolean;
15
+ /** Original renderer resource and configuration; interpreted by extensions. */
16
+ resource?: object;
17
+ config?: object;
18
+ };
19
+ export type SSRHeadPart = {
20
+ toString(): string;
21
+ };
22
+ export type SSRHeadData = Record<'htmlAttributes' | 'bodyAttributes' | 'title' | 'base' | 'link' | 'meta' | 'noscript' | 'script' | 'style', SSRHeadPart> & {
23
+ priority?: SSRHeadPart;
24
+ };
25
+ export type SSRRenderTerminal = {
26
+ status: 'complete';
27
+ } | {
28
+ status: 'fallback';
29
+ error: unknown;
30
+ } | {
31
+ status: 'error';
32
+ error: unknown;
33
+ } | {
34
+ status: 'cancelled';
35
+ reason: unknown;
36
+ };
37
+ export type SSRRenderAsset = {
38
+ url?: string;
39
+ filename?: string;
40
+ };
41
+ export type SSRAssetGroup<T extends SSRRenderAsset> = {
42
+ name: string;
43
+ assets: readonly T[];
44
+ };
45
+ export type SSRAssetTransformInfo<T extends SSRRenderAsset> = {
46
+ kind: 'style' | 'script';
47
+ source: 'loadable' | 'template';
48
+ template: string;
49
+ groups: readonly SSRAssetGroup<T>[];
50
+ createAsset: (url: string) => T;
51
+ };
52
+ export type SSRTemplateChunk = {
53
+ name: 'styles' | 'scripts' | 'data';
54
+ template: string;
55
+ placeholder: string;
56
+ content: string;
57
+ emittedAssets?: readonly string[];
58
+ attributes?: Readonly<Record<string, unknown>>;
59
+ };
60
+ export type SSRHtmlFormatting = {
61
+ attributesToString: (attributes: Record<string, unknown>) => string;
62
+ hasStylesheetLink: (template: string, href: string) => boolean | undefined;
63
+ };
64
+ export type SSRRouterData = {
65
+ loaderData?: unknown;
66
+ errors?: Record<string, unknown> | null;
67
+ };
68
+ export interface SSRRenderLifecycle {
69
+ /** Native asset objects keep their identity and are formatted after this hook. */
70
+ transformAssets?: <T extends SSRRenderAsset>(assets: readonly T[], info: SSRAssetTransformInfo<T>) => readonly T[];
71
+ /** Runs on each prepared chunk before native placeholder substitution. */
72
+ transformTemplateChunk?: (chunk: SSRTemplateChunk, formatting: SSRHtmlFormatting) => SSRTemplateChunk;
73
+ /** Raw router data is serialized by the native renderer; undefined uses its fallback. */
74
+ getRouterData?: () => SSRRouterData | undefined;
75
+ beforeReact?: () => void;
76
+ /** Runs before the completed body or shell's head data is read. */
77
+ completedBody?: (html: string, info: {
78
+ phase: 'complete' | 'shell';
79
+ }) => string;
80
+ getHeadData?: () => SSRHeadData | undefined;
81
+ /** Exactly one notification for this render attempt. */
82
+ onTerminal?: (terminal: SSRRenderTerminal) => void;
83
+ }
84
+ export type Collector = SSRRenderLifecycle & {
9
85
  collect?: (component: React.ReactElement) => React.ReactElement;
10
86
  effect: () => void | Promise<void>;
11
87
  };
@@ -13,10 +89,14 @@ import type React from 'react';
13
89
  import type { AsyncInterruptHook, CollectSyncHook, SyncHook } from '../hooks.js';
14
90
  export type OnBeforeRenderFn<RuntimeContext> = (context: RuntimeContext, interrupt: (info: any) => any) => Promise<any> | any;
15
91
  export type ExtendStringSSRCollectorsFn<RuntimeContext> = (context: RuntimeContext) => Collector;
16
- export type StringSSRCollectorsInfo = {
92
+ export type StringSSRCollectorsInfo<RuntimeContext = object> = {
17
93
  chunkSet: ChunkSet;
94
+ render: SSRRenderInfo<RuntimeContext>;
95
+ };
96
+ export type StreamSSRInfo<RuntimeContext = object> = SSRRenderInfo<RuntimeContext> & {
97
+ terminalMarker: string;
18
98
  };
19
- export interface StreamSSRExtender {
99
+ export interface StreamSSRExtender extends SSRRenderLifecycle {
20
100
  init?: (params: {
21
101
  rootElement: React.ReactElement;
22
102
  forceStream2String: boolean;
@@ -24,16 +104,34 @@ export interface StreamSSRExtender {
24
104
  modifyRootElement?: (rootElement: React.ReactElement) => React.ReactElement;
25
105
  getStyleTags?: () => string;
26
106
  processStream?: (stream: NodeJS.ReadWriteStream) => NodeJS.ReadWriteStream;
107
+ processReadableStream?: (stream: ReadableStream<Uint8Array>) => ReadableStream<Uint8Array>;
108
+ /** Body transforms run after all render transforms, preserving order in each phase. */
109
+ streamPhase?: 'render' | 'body';
27
110
  }
28
- export type ExtendStreamSSRFn = () => StreamSSRExtender;
111
+ export type ExtendStreamSSRFn<RuntimeContext = object> = (info: StreamSSRInfo<RuntimeContext>) => StreamSSRExtender;
29
112
  export type WrapRootFn = (root: React.ComponentType<any>) => React.ComponentType<any>;
113
+ export type ResolveComponentFn = (component: React.ComponentType<any>, options: {
114
+ name: string;
115
+ }) => React.ComponentType<any>;
30
116
  export type PickContextFn<RuntimeContext> = (context: RuntimeContext) => RuntimeContext;
117
+ export type RuntimeContextProjection<RuntimeContext> = {
118
+ internalContext: RuntimeContext;
119
+ publicContext: RuntimeContext;
120
+ };
121
+ export type TransformRuntimeContextFn<RuntimeContext> = (projection: RuntimeContextProjection<RuntimeContext>, options: {
122
+ /** Original request context, unchanged across callbacks in the pipeline. */
123
+ context: RuntimeContext;
124
+ /** Whether the application's RSC mode is enabled. */
125
+ isRsc: boolean;
126
+ }) => RuntimeContextProjection<RuntimeContext>;
31
127
  export type ConfigFn<RuntimeConfig> = () => RuntimeConfig;
32
128
  export type Hooks<RuntimeConfig, RuntimeContext> = {
33
129
  onBeforeRender: AsyncInterruptHook<OnBeforeRenderFn<RuntimeContext>>;
34
130
  wrapRoot: SyncHook<WrapRootFn>;
131
+ resolveComponent: SyncHook<ResolveComponentFn>;
35
132
  pickContext: SyncHook<PickContextFn<RuntimeContext>>;
133
+ transformRuntimeContext: SyncHook<TransformRuntimeContextFn<RuntimeContext>>;
36
134
  config: CollectSyncHook<ConfigFn<RuntimeConfig>>;
37
- extendStringSSRCollectors: CollectSyncHook<ExtendStringSSRCollectorsFn<StringSSRCollectorsInfo>>;
38
- extendStreamSSR: CollectSyncHook<ExtendStreamSSRFn>;
135
+ extendStringSSRCollectors: CollectSyncHook<ExtendStringSSRCollectorsFn<StringSSRCollectorsInfo<RuntimeContext>>>;
136
+ extendStreamSSR: CollectSyncHook<ExtendStreamSSRFn<RuntimeContext>>;
39
137
  };
@@ -1,4 +1,5 @@
1
1
  import type { ServerRoute } from '@modern-js/types';
2
+ import type { BffRuntimeFramework } from '../../server/run/types.js';
2
3
  import type { ServerPluginAPI } from './api.js';
3
4
  import type { Hooks } from './hooks.js';
4
5
  import type { ServerPlugin, ServerPluginExtends } from './plugin.js';
@@ -11,6 +12,7 @@ export type ServerContext<Extends extends ServerPluginExtends> = {
11
12
  appDirectory: string;
12
13
  apiDirectory?: string;
13
14
  lambdaDirectory?: string;
15
+ bffRuntimeFramework?: BffRuntimeFramework;
14
16
  internalDirectory?: string;
15
17
  sharedDirectory?: string;
16
18
  distDirectory?: string;
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "modern",
18
18
  "modern.js"
19
19
  ],
20
- "version": "3.9.0-ultramodern.4",
20
+ "version": "3.9.0-ultramodern.6",
21
21
  "types": "./dist/types/index.d.ts",
22
22
  "main": "./dist/cjs/index.js",
23
23
  "exports": {
@@ -79,15 +79,15 @@
79
79
  }
80
80
  },
81
81
  "dependencies": {
82
- "@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.9.0-ultramodern.4",
83
- "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.0-ultramodern.4",
84
- "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.0-ultramodern.4",
82
+ "@modern-js/runtime-utils": "npm:@bleedingdev/modern-js-runtime-utils@3.9.0-ultramodern.6",
83
+ "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.0-ultramodern.6",
84
+ "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.0-ultramodern.6",
85
85
  "@rsbuild/core": "2.2.3",
86
86
  "@swc/helpers": "^0.5.23",
87
87
  "jiti": "^2.7.0"
88
88
  },
89
89
  "devDependencies": {
90
- "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.0-ultramodern.4",
90
+ "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.0-ultramodern.6",
91
91
  "@rslib/core": "1.0.0",
92
92
  "@types/node": "^26.4.1",
93
93
  "@types/react": "^19.2.18",