@bleedingdev/modern-js-renderer-octane 0.0.0-stage → 3.9.3-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.
- package/LICENSE +21 -0
- package/bin/octane-tsc.mjs +4 -0
- package/dist/cjs/bootstrap.js +68 -0
- package/dist/cjs/client.js +421 -0
- package/dist/cjs/entry-application.js +88 -0
- package/dist/cjs/entry-client.js +95 -0
- package/dist/cjs/entry-server.js +135 -0
- package/dist/cjs/federation-context.js +72 -0
- package/dist/cjs/federation.js +205 -0
- package/dist/cjs/i18n/I18nProvider.js +59 -0
- package/dist/cjs/i18n/LocalizedLink.js +80 -0
- package/dist/cjs/i18n/context.js +41 -0
- package/dist/cjs/i18n/index.js +83 -0
- package/dist/cjs/i18n/languageSync.js +99 -0
- package/dist/cjs/i18n/types.js +18 -0
- package/dist/cjs/i18n/useI18n.js +110 -0
- package/dist/cjs/i18n-external-snapshot.js +645 -0
- package/dist/cjs/index.js +46 -0
- package/dist/cjs/manifest.js +167 -0
- package/dist/cjs/plugin/compiler.js +122 -0
- package/dist/cjs/plugin/create.js +266 -0
- package/dist/cjs/plugin/index.js +151 -0
- package/dist/cjs/plugin/profile.js +91 -0
- package/dist/cjs/plugin/source.js +56 -0
- package/dist/cjs/router-client.js +139 -0
- package/dist/cjs/router-external-snapshot.js +291 -0
- package/dist/cjs/router-handler.js +171 -0
- package/dist/cjs/router-server-cleanup.js +46 -0
- package/dist/cjs/router-server-snapshot.js +405 -0
- package/dist/cjs/router-server.js +100 -0
- package/dist/cjs/router-snapshot.js +270 -0
- package/dist/cjs/router.js +218 -0
- package/dist/cjs/routes.js +190 -0
- package/dist/cjs/server.js +245 -0
- package/dist/cjs/typecheck.js +615 -0
- package/dist/cjs/worker-federation-context.js +63 -0
- package/dist/cjs/worker-federation-contexts.js +97 -0
- package/dist/cjs/worker-federation.js +97 -0
- package/dist/esm/bootstrap.mjs +24 -0
- package/dist/esm/client.mjs +377 -0
- package/dist/esm/entry-application.mjs +44 -0
- package/dist/esm/entry-client.mjs +57 -0
- package/dist/esm/entry-server.mjs +91 -0
- package/dist/esm/federation-context.mjs +25 -0
- package/dist/esm/federation.mjs +167 -0
- package/dist/esm/i18n/I18nProvider.mjs +21 -0
- package/dist/esm/i18n/LocalizedLink.mjs +42 -0
- package/dist/esm/i18n/context.mjs +3 -0
- package/dist/esm/i18n/index.mjs +8 -0
- package/dist/esm/i18n/languageSync.mjs +61 -0
- package/dist/esm/i18n/types.mjs +0 -0
- package/dist/esm/i18n/useI18n.mjs +72 -0
- package/dist/esm/i18n-external-snapshot.mjs +576 -0
- package/dist/esm/index.mjs +8 -0
- package/dist/esm/manifest.mjs +117 -0
- package/dist/esm/router-client.mjs +98 -0
- package/dist/esm/router-external-snapshot.mjs +244 -0
- package/dist/esm/router-handler.mjs +133 -0
- package/dist/esm/router-server-cleanup.mjs +8 -0
- package/dist/esm/router-server-snapshot.mjs +367 -0
- package/dist/esm/router-server.mjs +11 -0
- package/dist/esm/router-snapshot.mjs +199 -0
- package/dist/esm/router.mjs +94 -0
- package/dist/esm/routes.mjs +134 -0
- package/dist/esm/server.mjs +204 -0
- package/dist/esm/worker-federation-context.mjs +19 -0
- package/dist/esm/worker-federation-contexts.mjs +47 -0
- package/dist/esm/worker-federation.mjs +59 -0
- package/dist/esm-node/bootstrap.mjs +24 -0
- package/dist/esm-node/manifest.mjs +117 -0
- package/dist/esm-node/plugin/compiler.mjs +67 -0
- package/dist/esm-node/plugin/create.mjs +228 -0
- package/dist/esm-node/plugin/index.mjs +103 -0
- package/dist/esm-node/plugin/profile.mjs +53 -0
- package/dist/esm-node/plugin/source.mjs +7 -0
- package/dist/esm-node/typecheck.mjs +560 -0
- package/dist/types/bootstrap.d.ts +10 -0
- package/dist/types/client.d.ts +40 -0
- package/dist/types/entry-application.d.ts +19 -0
- package/dist/types/entry-client.d.ts +10 -0
- package/dist/types/entry-server.d.ts +14 -0
- package/dist/types/federation-context.d.ts +28 -0
- package/dist/types/federation.d.ts +20 -0
- package/dist/types/i18n/I18nProvider.d.ts +8 -0
- package/dist/types/i18n/LocalizedLink.d.ts +14 -0
- package/dist/types/i18n/context.d.ts +9 -0
- package/dist/types/i18n/index.d.ts +9 -0
- package/dist/types/i18n/languageSync.d.ts +26 -0
- package/dist/types/i18n/types.d.ts +34 -0
- package/dist/types/i18n/useI18n.d.ts +21 -0
- package/dist/types/i18n-external-snapshot.d.ts +43 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/manifest.d.ts +34 -0
- package/dist/types/plugin/compiler-manifest.d.cts +10 -0
- package/dist/types/plugin/compiler.d.ts +5 -0
- package/dist/types/plugin/create.d.ts +23 -0
- package/dist/types/plugin/index.d.ts +3 -0
- package/dist/types/plugin/profile.d.ts +2 -0
- package/dist/types/plugin/source.d.ts +1 -0
- package/dist/types/plugin/svg-component-template.d.cts +6 -0
- package/dist/types/router-client.d.ts +12 -0
- package/dist/types/router-external-snapshot.d.ts +10 -0
- package/dist/types/router-handler.d.ts +13 -0
- package/dist/types/router-server-cleanup.d.ts +3 -0
- package/dist/types/router-server-snapshot.d.ts +15 -0
- package/dist/types/router-server.d.ts +11 -0
- package/dist/types/router-snapshot.d.ts +14 -0
- package/dist/types/router.d.ts +30 -0
- package/dist/types/routes.d.ts +20 -0
- package/dist/types/server.d.ts +47 -0
- package/dist/types/typecheck.d.ts +31 -0
- package/dist/types/worker-federation-context.d.ts +34 -0
- package/dist/types/worker-federation-contexts.d.ts +25 -0
- package/dist/types/worker-federation.d.ts +20 -0
- package/package.json +278 -4
- package/src/bootstrap.ts +60 -0
- package/src/client.ts +568 -0
- package/src/entry-application.ts +76 -0
- package/src/entry-client.ts +90 -0
- package/src/entry-server.ts +153 -0
- package/src/federation-context.ts +53 -0
- package/src/federation.ts +307 -0
- package/src/i18n/I18nProvider.ts +47 -0
- package/src/i18n/LocalizedLink.ts +86 -0
- package/src/i18n/context.ts +12 -0
- package/src/i18n/index.ts +31 -0
- package/src/i18n/languageSync.ts +132 -0
- package/src/i18n/types.ts +36 -0
- package/src/i18n/useI18n.ts +119 -0
- package/src/i18n-external-snapshot.ts +803 -0
- package/src/index.ts +10 -0
- package/src/manifest.ts +253 -0
- package/src/plugin/compiler-manifest.cjs +204 -0
- package/src/plugin/compiler.ts +104 -0
- package/src/plugin/create.ts +273 -0
- package/src/plugin/index.ts +107 -0
- package/src/plugin/profile.ts +50 -0
- package/src/plugin/source.ts +16 -0
- package/src/plugin/svg-component-template.cjs +17 -0
- package/src/router-client.ts +144 -0
- package/src/router-external-snapshot.ts +363 -0
- package/src/router-handler.ts +185 -0
- package/src/router-server-cleanup.ts +11 -0
- package/src/router-server-snapshot.ts +564 -0
- package/src/router-server.ts +21 -0
- package/src/router-snapshot.ts +251 -0
- package/src/router.ts +192 -0
- package/src/routes.ts +274 -0
- package/src/server.ts +340 -0
- package/src/typecheck.ts +723 -0
- package/src/worker-federation-context.ts +51 -0
- package/src/worker-federation-contexts.ts +91 -0
- package/src/worker-federation.ts +120 -0
- package/README.md +0 -3
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { WorkerFederationTransport } from '@modern-js/renderer-core/worker-federation';
|
|
2
|
+
import { createContext, createElement } from 'octane';
|
|
3
|
+
import {
|
|
4
|
+
FederationApplication,
|
|
5
|
+
type OctaneFederationScope,
|
|
6
|
+
} from './federation-context';
|
|
7
|
+
|
|
8
|
+
export interface OctaneWorkerFederationScope {
|
|
9
|
+
readonly transport: WorkerFederationTransport;
|
|
10
|
+
/** Compiled entry fallback; localized providers supply their live language. */
|
|
11
|
+
readonly locale: string;
|
|
12
|
+
/** Own document disposal; each lazy admission also owns its waiter deadline. */
|
|
13
|
+
readonly signal?: AbortSignal;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type OctaneWorkerFederationFactory = (
|
|
17
|
+
signal: AbortSignal,
|
|
18
|
+
) => OctaneWorkerFederationScope;
|
|
19
|
+
|
|
20
|
+
/** Each native document owns its transport and captured publisher authorities. */
|
|
21
|
+
export const WorkerFederationContext =
|
|
22
|
+
createContext<OctaneWorkerFederationScope | null>(null);
|
|
23
|
+
|
|
24
|
+
export function WorkerFederationRoot(props: {
|
|
25
|
+
readonly scope: OctaneWorkerFederationScope;
|
|
26
|
+
readonly children?: unknown;
|
|
27
|
+
}) {
|
|
28
|
+
return createElement(WorkerFederationContext, {
|
|
29
|
+
value: props.scope,
|
|
30
|
+
children: props.children,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Stable native root used for startup and application updates alike. */
|
|
35
|
+
export function WorkerFederationApplication(props: {
|
|
36
|
+
readonly scope: OctaneWorkerFederationScope;
|
|
37
|
+
readonly federation?: OctaneFederationScope;
|
|
38
|
+
readonly application: Parameters<
|
|
39
|
+
typeof FederationApplication
|
|
40
|
+
>[0]['application'];
|
|
41
|
+
}) {
|
|
42
|
+
return createElement(WorkerFederationRoot, {
|
|
43
|
+
scope: props.scope,
|
|
44
|
+
children: props.federation
|
|
45
|
+
? createElement(FederationApplication, {
|
|
46
|
+
scope: props.federation,
|
|
47
|
+
application: props.application,
|
|
48
|
+
})
|
|
49
|
+
: createElement(props.application.default, props.application.props),
|
|
50
|
+
});
|
|
51
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { NativeLocationRewrite } from '@modern-js/renderer-core/router';
|
|
2
|
+
import {
|
|
3
|
+
type Context,
|
|
4
|
+
type ExternalSnapshotContextCodec,
|
|
5
|
+
registerExternalSnapshotContext,
|
|
6
|
+
useContext,
|
|
7
|
+
} from 'octane';
|
|
8
|
+
|
|
9
|
+
export const OCTANE_WORKER_CONTEXT_KEYS = Object.freeze({
|
|
10
|
+
router: 'ultramodern.octane.router-context.v1',
|
|
11
|
+
match: 'ultramodern.octane.match-context.v1',
|
|
12
|
+
i18n: 'ultramodern.octane.i18n-context.v1',
|
|
13
|
+
} as const);
|
|
14
|
+
|
|
15
|
+
type OctaneWorkerContextKey =
|
|
16
|
+
(typeof OCTANE_WORKER_CONTEXT_KEYS)[keyof typeof OCTANE_WORKER_CONTEXT_KEYS];
|
|
17
|
+
|
|
18
|
+
export interface OctaneWorkerContextCodec<T>
|
|
19
|
+
extends ExternalSnapshotContextCodec<T> {
|
|
20
|
+
readonly key: OctaneWorkerContextKey;
|
|
21
|
+
readonly dispose?: (value: T) => void | PromiseLike<void>;
|
|
22
|
+
readonly isProvided: (value: T) => boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const builtinKeys = Object.values(OCTANE_WORKER_CONTEXT_KEYS);
|
|
26
|
+
const contexts = new Map<OctaneWorkerContextKey, () => boolean>();
|
|
27
|
+
|
|
28
|
+
/** Optional renderer modules register their actual native context identities. */
|
|
29
|
+
export function registerOctaneWorkerContext<T>(
|
|
30
|
+
context: Context<T>,
|
|
31
|
+
codec: OctaneWorkerContextCodec<T>,
|
|
32
|
+
): () => void {
|
|
33
|
+
const { key, isProvided } = codec;
|
|
34
|
+
if (!builtinKeys.includes(key) || typeof isProvided !== 'function')
|
|
35
|
+
throw new TypeError('Invalid Octane Worker builtin context codec');
|
|
36
|
+
|
|
37
|
+
const unregister = registerExternalSnapshotContext(context, codec);
|
|
38
|
+
const hasProvider = () => isProvided(useContext(context));
|
|
39
|
+
contexts.set(key, hasProvider);
|
|
40
|
+
|
|
41
|
+
return () => {
|
|
42
|
+
if (contexts.get(key) !== hasProvider) return;
|
|
43
|
+
unregister();
|
|
44
|
+
contexts.delete(key);
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Read live providers on every render; explicit requirements retain native validation. */
|
|
49
|
+
export function useOctaneWorkerContextKeys(
|
|
50
|
+
explicit: readonly string[] = [],
|
|
51
|
+
): readonly string[] {
|
|
52
|
+
const selected: string[] = [];
|
|
53
|
+
for (const key of builtinKeys) {
|
|
54
|
+
const hasProvider = contexts.get(key);
|
|
55
|
+
if (hasProvider?.() && !explicit.includes(key)) selected.push(key);
|
|
56
|
+
}
|
|
57
|
+
return [...selected, ...explicit];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface OctaneWorkerRouterRewrite {
|
|
61
|
+
readonly capture: (rewrite: NativeLocationRewrite) => unknown;
|
|
62
|
+
readonly restore: (descriptor: unknown) => NativeLocationRewrite;
|
|
63
|
+
}
|
|
64
|
+
let routerRewrite: OctaneWorkerRouterRewrite | undefined;
|
|
65
|
+
|
|
66
|
+
/** The optional i18n owner supplies its own native rewrite provenance. */
|
|
67
|
+
export function registerOctaneWorkerRouterRewrite(
|
|
68
|
+
codec: OctaneWorkerRouterRewrite,
|
|
69
|
+
): () => void {
|
|
70
|
+
if (
|
|
71
|
+
routerRewrite ||
|
|
72
|
+
typeof codec.capture !== 'function' ||
|
|
73
|
+
typeof codec.restore !== 'function'
|
|
74
|
+
)
|
|
75
|
+
throw new TypeError(
|
|
76
|
+
'Invalid or duplicate Octane Worker router rewrite codec',
|
|
77
|
+
);
|
|
78
|
+
const captured = Object.freeze({
|
|
79
|
+
capture: codec.capture,
|
|
80
|
+
restore: codec.restore,
|
|
81
|
+
});
|
|
82
|
+
routerRewrite = captured;
|
|
83
|
+
return () => {
|
|
84
|
+
if (routerRewrite === captured) routerRewrite = undefined;
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
export function getOctaneWorkerRouterRewrite():
|
|
88
|
+
| OctaneWorkerRouterRewrite
|
|
89
|
+
| undefined {
|
|
90
|
+
return routerRewrite;
|
|
91
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { NativeWorkerDispatchOptions } from '@modern-js/renderer-core/server';
|
|
2
|
+
import {
|
|
3
|
+
type AdmitWorkerRendererContract,
|
|
4
|
+
createWorkerFederationHandler,
|
|
5
|
+
createWorkerFederationTransport,
|
|
6
|
+
} from '@modern-js/renderer-core/worker-federation';
|
|
7
|
+
import {
|
|
8
|
+
type ExternalSnapshotRenderOptions,
|
|
9
|
+
prepareExternalSnapshotRequest,
|
|
10
|
+
releasePreparedExternalSnapshotRequest,
|
|
11
|
+
renderExternalSnapshot,
|
|
12
|
+
type ServerRenderNode,
|
|
13
|
+
serializeExternalSnapshot,
|
|
14
|
+
} from 'octane/server';
|
|
15
|
+
import { createFederationScope, FederationContext } from './federation-context';
|
|
16
|
+
import { WorkerFederationContext } from './worker-federation-context';
|
|
17
|
+
|
|
18
|
+
type NativeSnapshotRequest = Awaited<
|
|
19
|
+
ReturnType<typeof prepareExternalSnapshotRequest>
|
|
20
|
+
>;
|
|
21
|
+
type HandlerOptions = Parameters<
|
|
22
|
+
typeof createWorkerFederationHandler<NativeSnapshotRequest>
|
|
23
|
+
>[0];
|
|
24
|
+
|
|
25
|
+
function isNativeWorkerComponent(
|
|
26
|
+
value: unknown,
|
|
27
|
+
): value is Extract<ServerRenderNode, (props: never) => unknown> {
|
|
28
|
+
return typeof value === 'function';
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** The compiled registry pins its renderer publication and literal imports. */
|
|
32
|
+
export interface OctaneWorkerFederationRegistry {
|
|
33
|
+
initialize(
|
|
34
|
+
options: Omit<HandlerOptions, 'publication' | 'exposes'> & {
|
|
35
|
+
publication: unknown;
|
|
36
|
+
},
|
|
37
|
+
): (request: Request) => Promise<Response | undefined>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Created per dispatch; no publisher or native snapshot cache crosses documents. */
|
|
41
|
+
export function createNativeWorkerFederationRuntime<Bindings extends object>(
|
|
42
|
+
options: NativeWorkerDispatchOptions<Bindings>,
|
|
43
|
+
compiler: {
|
|
44
|
+
readonly admitRendererContract: AdmitWorkerRendererContract;
|
|
45
|
+
readonly registry?: OctaneWorkerFederationRegistry;
|
|
46
|
+
},
|
|
47
|
+
) {
|
|
48
|
+
const { resources } = options;
|
|
49
|
+
const bindings = options.bindings;
|
|
50
|
+
const transport = resources.workerFederationServices?.length
|
|
51
|
+
? createWorkerFederationTransport({
|
|
52
|
+
admitRendererContract: compiler.admitRendererContract,
|
|
53
|
+
services: resources.workerFederationServices.map(service => {
|
|
54
|
+
const binding: unknown =
|
|
55
|
+
bindings && Reflect.get(bindings, service.binding);
|
|
56
|
+
if (
|
|
57
|
+
!binding ||
|
|
58
|
+
(typeof binding !== 'object' && typeof binding !== 'function') ||
|
|
59
|
+
!('fetch' in binding) ||
|
|
60
|
+
typeof binding.fetch !== 'function'
|
|
61
|
+
)
|
|
62
|
+
throw new Error(
|
|
63
|
+
`Native Worker federation requires service binding ${service.binding}.`,
|
|
64
|
+
);
|
|
65
|
+
return { ...service, fetch: binding.fetch.bind(binding) };
|
|
66
|
+
}),
|
|
67
|
+
})
|
|
68
|
+
: undefined;
|
|
69
|
+
let handle: ((request: Request) => Promise<Response | undefined>) | undefined;
|
|
70
|
+
if (resources.workerFederation) {
|
|
71
|
+
if (!compiler.registry || !resources.workerFederationManifestUrl)
|
|
72
|
+
throw new Error(
|
|
73
|
+
'Native Worker federation requires its compiled expose registry and pinned manifest URL.',
|
|
74
|
+
);
|
|
75
|
+
handle = compiler.registry.initialize({
|
|
76
|
+
publication: resources.workerFederation.worker,
|
|
77
|
+
manifestUrl: resources.workerFederationManifestUrl,
|
|
78
|
+
admitRendererContract: compiler.admitRendererContract,
|
|
79
|
+
admitNativeRequest(payload, { admitted, signal }) {
|
|
80
|
+
const initializeContexts: ExternalSnapshotRenderOptions['initializeContexts'] =
|
|
81
|
+
transport
|
|
82
|
+
? (provide, request) => {
|
|
83
|
+
provide(
|
|
84
|
+
FederationContext,
|
|
85
|
+
createFederationScope(undefined, true, request.nonce),
|
|
86
|
+
);
|
|
87
|
+
provide(WorkerFederationContext, {
|
|
88
|
+
transport,
|
|
89
|
+
locale: admitted.locale,
|
|
90
|
+
signal,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
: undefined;
|
|
94
|
+
return prepareExternalSnapshotRequest(payload, {
|
|
95
|
+
authority: admitted.coordinate.native,
|
|
96
|
+
signal,
|
|
97
|
+
...(initializeContexts ? { initializeContexts } : {}),
|
|
98
|
+
});
|
|
99
|
+
},
|
|
100
|
+
releaseNativeRequest: releasePreparedExternalSnapshotRequest,
|
|
101
|
+
async renderNativeSnapshot(module, request, { admitted }) {
|
|
102
|
+
const component =
|
|
103
|
+
module && typeof module === 'object' && 'default' in module
|
|
104
|
+
? module.default
|
|
105
|
+
: undefined;
|
|
106
|
+
if (!isNativeWorkerComponent(component))
|
|
107
|
+
throw new TypeError(
|
|
108
|
+
`Native Worker expose ${admitted.expose} requires a default Octane component.`,
|
|
109
|
+
);
|
|
110
|
+
return serializeExternalSnapshot(
|
|
111
|
+
await renderExternalSnapshot(component, request),
|
|
112
|
+
);
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
transport,
|
|
118
|
+
handleRequest: handle ?? (() => Promise.resolve(undefined)),
|
|
119
|
+
};
|
|
120
|
+
}
|
package/README.md
DELETED