@bleedingdev/modern-js-renderer-octane 3.9.3-ultramodern.8 → 3.9.3-ultramodern.9

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 (61) hide show
  1. package/dist/cjs/client.js +56 -6
  2. package/dist/cjs/entry-application.js +7 -2
  3. package/dist/cjs/entry-client.js +3 -0
  4. package/dist/cjs/entry-server.js +11 -3
  5. package/dist/cjs/federation.js +108 -6
  6. package/dist/cjs/i18n/LocalizedLink.js +24 -33
  7. package/dist/cjs/i18n/index.js +0 -3
  8. package/dist/cjs/i18n-external-snapshot.js +645 -0
  9. package/dist/cjs/plugin/index.js +1 -1
  10. package/dist/cjs/plugin/profile.js +5 -4
  11. package/dist/cjs/router-external-snapshot.js +263 -0
  12. package/dist/cjs/server.js +15 -2
  13. package/dist/cjs/worker-federation-context.js +63 -0
  14. package/dist/cjs/worker-federation-contexts.js +97 -0
  15. package/dist/cjs/worker-federation.js +97 -0
  16. package/dist/esm/client.mjs +56 -6
  17. package/dist/esm/entry-application.mjs +7 -2
  18. package/dist/esm/entry-client.mjs +3 -0
  19. package/dist/esm/entry-server.mjs +8 -3
  20. package/dist/esm/federation.mjs +110 -8
  21. package/dist/esm/i18n/LocalizedLink.mjs +24 -30
  22. package/dist/esm/i18n/index.mjs +1 -1
  23. package/dist/esm/i18n-external-snapshot.mjs +576 -0
  24. package/dist/esm/router-external-snapshot.mjs +216 -0
  25. package/dist/esm/server.mjs +15 -2
  26. package/dist/esm/worker-federation-context.mjs +19 -0
  27. package/dist/esm/worker-federation-contexts.mjs +47 -0
  28. package/dist/esm/worker-federation.mjs +59 -0
  29. package/dist/esm-node/plugin/index.mjs +1 -1
  30. package/dist/esm-node/plugin/profile.mjs +5 -4
  31. package/dist/types/client.d.ts +5 -1
  32. package/dist/types/entry-client.d.ts +2 -0
  33. package/dist/types/entry-server.d.ts +4 -1
  34. package/dist/types/federation.d.ts +2 -0
  35. package/dist/types/i18n/LocalizedLink.d.ts +5 -32
  36. package/dist/types/i18n/context.d.ts +1 -1
  37. package/dist/types/i18n/index.d.ts +1 -1
  38. package/dist/types/i18n-external-snapshot.d.ts +43 -0
  39. package/dist/types/router-external-snapshot.d.ts +10 -0
  40. package/dist/types/server.d.ts +3 -0
  41. package/dist/types/worker-federation-context.d.ts +34 -0
  42. package/dist/types/worker-federation-contexts.d.ts +25 -0
  43. package/dist/types/worker-federation.d.ts +20 -0
  44. package/package.json +69 -12
  45. package/src/client.ts +99 -16
  46. package/src/entry-application.ts +7 -3
  47. package/src/entry-client.ts +10 -0
  48. package/src/entry-server.ts +17 -6
  49. package/src/federation.ts +159 -15
  50. package/src/i18n/LocalizedLink.ts +46 -72
  51. package/src/i18n/context.ts +1 -1
  52. package/src/i18n/index.ts +1 -5
  53. package/src/i18n-external-snapshot.ts +803 -0
  54. package/src/plugin/compiler-manifest.cjs +27 -1
  55. package/src/plugin/index.ts +1 -1
  56. package/src/plugin/profile.ts +6 -4
  57. package/src/router-external-snapshot.ts +306 -0
  58. package/src/server.ts +29 -4
  59. package/src/worker-federation-context.ts +51 -0
  60. package/src/worker-federation-contexts.ts +91 -0
  61. package/src/worker-federation.ts +120 -0
@@ -0,0 +1,216 @@
1
+ import { assertDefaultRouterRenderHost, associateRouterRenderProfile, captureRouterRenderSnapshot, createRouterRenderRouteTree, defaultParseSearch, defaultStringifySearch, disposeRouterRenderSnapshot, getRouterRenderProfile, matchContext, registerRouterRenderProfile, restoreRouterRenderSnapshot, routerContext } from "@octanejs/tanstack-router";
2
+ import { OCTANE_WORKER_CONTEXT_KEYS, getOctaneWorkerRouterRewrite, registerOctaneWorkerContext } from "./worker-federation-contexts.mjs";
3
+ const OCTANE_FILE_ROUTE_SNAPSHOT_PROFILE = Object.freeze({
4
+ key: 'ultramodern.file-routes',
5
+ version: '1'
6
+ });
7
+ const origins = new WeakMap();
8
+ let profileRegistered = false;
9
+ function plainRecord(value) {
10
+ return null !== value && 'object' == typeof value && [
11
+ Object.prototype,
12
+ null
13
+ ].includes(Object.getPrototypeOf(value));
14
+ }
15
+ function record(value, fields) {
16
+ if (!plainRecord(value)) throw new TypeError('Worker router context requires a plain record');
17
+ for (const key of Reflect.ownKeys(value)){
18
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
19
+ if ('string' != typeof key || fields && !fields.includes(key) || !descriptor || !descriptor.enumerable || !('value' in descriptor)) throw new TypeError('Unknown Worker router context field or accessor');
20
+ }
21
+ return value;
22
+ }
23
+ function nonempty(value) {
24
+ if ('string' != typeof value || !value.trim() || value.length > 1024) throw new TypeError('Invalid Worker router identity');
25
+ return value;
26
+ }
27
+ function publicContext(value) {
28
+ const context = record(value, [
29
+ 'ultramodern'
30
+ ]);
31
+ const metadata = record(context.ultramodern, [
32
+ 'rendererIdentity'
33
+ ]);
34
+ const identity = record(metadata.rendererIdentity, [
35
+ 'renderer',
36
+ 'appId',
37
+ 'entryName',
38
+ 'protocolVersion',
39
+ 'buildId'
40
+ ]);
41
+ if ('octane' !== identity.renderer || 1 !== identity.protocolVersion) throw new TypeError('Unsupported Worker router identity');
42
+ return Object.freeze({
43
+ ultramodern: Object.freeze({
44
+ rendererIdentity: Object.freeze({
45
+ renderer: 'octane',
46
+ appId: nonempty(identity.appId),
47
+ entryName: nonempty(identity.entryName),
48
+ protocolVersion: 1,
49
+ buildId: nonempty(identity.buildId)
50
+ })
51
+ })
52
+ });
53
+ }
54
+ function localizedUrls(value) {
55
+ if (void 0 === value || 'boolean' == typeof value) return value;
56
+ const input = record(value);
57
+ const result = {};
58
+ for (const [path, translations] of Object.entries(input)){
59
+ const names = {};
60
+ for (const [language, target] of Object.entries(record(translations)))names[nonempty(language)] = nonempty(target);
61
+ result[path] = names;
62
+ }
63
+ return result;
64
+ }
65
+ function rewriteDescriptor(value) {
66
+ if (void 0 === value) return;
67
+ const input = record(value, [
68
+ 'language',
69
+ 'languages',
70
+ 'localisedUrls'
71
+ ]);
72
+ if (!Array.isArray(input.languages) || !input.languages.length || input.languages.length > 64) throw new TypeError('Invalid Worker router i18n languages');
73
+ const languages = input.languages.map(nonempty);
74
+ const language = nonempty(input.language);
75
+ if (new Set(languages).size !== languages.length || !languages.includes(language)) throw new TypeError('Invalid Worker router i18n language');
76
+ const urls = localizedUrls(input.localisedUrls);
77
+ return {
78
+ language,
79
+ languages,
80
+ ...void 0 === urls ? {} : {
81
+ localisedUrls: urls
82
+ }
83
+ };
84
+ }
85
+ function nativeRewriteDescriptor(router) {
86
+ if (!router.options.rewrite) return;
87
+ const known = getOctaneWorkerRouterRewrite()?.capture(router.options.rewrite);
88
+ if (!known) throw new TypeError('Custom router rewrite requires an exact Worker profile');
89
+ const descriptor = rewriteDescriptor(known);
90
+ if (!descriptor) throw new TypeError('Missing native router rewrite provenance');
91
+ return {
92
+ language: descriptor.language,
93
+ languages: [
94
+ ...descriptor.languages
95
+ ],
96
+ ...void 0 === descriptor.localisedUrls ? {} : {
97
+ localisedUrls: descriptor.localisedUrls
98
+ }
99
+ };
100
+ }
101
+ function validateDefaultSnapshot(snapshot) {
102
+ publicContext(snapshot.publicContext);
103
+ rewriteDescriptor(snapshot.i18n);
104
+ }
105
+ function ensureDefaultProfile() {
106
+ if (profileRegistered) return;
107
+ registerRouterRenderProfile({
108
+ id: OCTANE_FILE_ROUTE_SNAPSHOT_PROFILE,
109
+ assertHost: (router, snapshot)=>{
110
+ const origin = origins.get(router);
111
+ if (!origin || origin.rewrite !== router.options.rewrite || JSON.stringify(publicContext(router.options.context)) !== JSON.stringify(origin.publicContext)) throw new TypeError('Generated Worker router origin changed');
112
+ assertDefaultRouterRenderHost(router, void 0 !== snapshot.i18n);
113
+ validateDefaultSnapshot(snapshot);
114
+ if (JSON.stringify(nativeRewriteDescriptor(router)) !== JSON.stringify(snapshot.i18n)) throw new TypeError('Worker router rewrite differs from its native provenance');
115
+ },
116
+ createRoutingTree: (snapshot)=>{
117
+ validateDefaultSnapshot(snapshot);
118
+ return createRouterRenderRouteTree(snapshot.routes);
119
+ },
120
+ routingOptions: (snapshot)=>{
121
+ const defaults = {
122
+ parseSearch: defaultParseSearch,
123
+ stringifySearch: defaultStringifySearch
124
+ };
125
+ const i18n = rewriteDescriptor(snapshot.i18n);
126
+ if (!i18n) return defaults;
127
+ const codec = getOctaneWorkerRouterRewrite();
128
+ if (!codec) throw new TypeError('Missing owning Worker router i18n codec');
129
+ return {
130
+ ...defaults,
131
+ rewrite: codec.restore(i18n)
132
+ };
133
+ }
134
+ });
135
+ profileRegistered = true;
136
+ }
137
+ function associateOctaneFileRouteSnapshot(router) {
138
+ ensureDefaultProfile();
139
+ const context = publicContext(router.options.context);
140
+ origins.set(router, {
141
+ publicContext: context,
142
+ rewrite: router.options.rewrite
143
+ });
144
+ associateRouterRenderProfile(router, {
145
+ id: OCTANE_FILE_ROUTE_SNAPSHOT_PROFILE,
146
+ publicContext: context
147
+ });
148
+ }
149
+ function captureOctaneRouterSnapshot(router) {
150
+ const origin = origins.get(router);
151
+ const declared = getRouterRenderProfile(router);
152
+ if (origin && declared?.key === OCTANE_FILE_ROUTE_SNAPSHOT_PROFILE.key && declared.version === OCTANE_FILE_ROUTE_SNAPSHOT_PROFILE.version) {
153
+ const i18n = nativeRewriteDescriptor(router);
154
+ associateRouterRenderProfile(router, {
155
+ id: OCTANE_FILE_ROUTE_SNAPSHOT_PROFILE,
156
+ publicContext: origin.publicContext,
157
+ ...void 0 === i18n ? {} : {
158
+ i18n
159
+ }
160
+ });
161
+ }
162
+ return captureRouterRenderSnapshot(router);
163
+ }
164
+ let registrations = 0;
165
+ let releaseContexts;
166
+ function registerOctaneRouterWorkerContexts() {
167
+ ensureDefaultProfile();
168
+ if (!releaseContexts) {
169
+ const releaseRouter = registerOctaneWorkerContext(routerContext, {
170
+ key: OCTANE_WORKER_CONTEXT_KEYS.router,
171
+ encode: (value)=>{
172
+ if (!value) throw new TypeError('Missing native router provider');
173
+ return captureOctaneRouterSnapshot(value);
174
+ },
175
+ decode: (value, signal)=>restoreRouterRenderSnapshot(value, {
176
+ signal
177
+ }),
178
+ dispose: (value)=>{
179
+ if (value) disposeRouterRenderSnapshot(value);
180
+ },
181
+ isProvided: (value)=>void 0 !== value
182
+ });
183
+ try {
184
+ const releaseMatch = registerOctaneWorkerContext(matchContext, {
185
+ key: OCTANE_WORKER_CONTEXT_KEYS.match,
186
+ encode: nonempty,
187
+ decode: nonempty,
188
+ validate: (value, readContext)=>{
189
+ const selected = readContext(routerContext);
190
+ const router = selected.present ? selected.value : void 0;
191
+ const current = router?.state.matches.find((match)=>match.routeId === value);
192
+ if (!router || !current || 'string' != typeof value || router.stores.getMatchStore(value).get() !== current) throw new TypeError('Worker match context requires its selected native router and a current match');
193
+ },
194
+ isProvided: (value)=>void 0 !== value
195
+ });
196
+ releaseContexts = ()=>{
197
+ releaseMatch();
198
+ releaseRouter();
199
+ };
200
+ } catch (error) {
201
+ releaseRouter();
202
+ throw error;
203
+ }
204
+ }
205
+ registrations++;
206
+ let released = false;
207
+ return ()=>{
208
+ if (released) return;
209
+ released = true;
210
+ if (0 === --registrations) {
211
+ releaseContexts?.();
212
+ releaseContexts = void 0;
213
+ }
214
+ };
215
+ }
216
+ export { OCTANE_FILE_ROUTE_SNAPSHOT_PROFILE, associateOctaneFileRouteSnapshot, captureOctaneRouterSnapshot, registerOctaneRouterWorkerContexts };
@@ -4,6 +4,7 @@ import { transformReadableStreamWithRouter } from "@octanejs/tanstack-router/ssr
4
4
  import { createElement, earlySignalBootstrapScript, renderToReadableStream } from "octane/server";
5
5
  import { assertNativeHydrationBuildId, assertOctaneIdentity } from "./bootstrap.mjs";
6
6
  import { FederationRoot, createFederationScope } from "./federation-context.mjs";
7
+ import { WorkerFederationRoot } from "./worker-federation-context.mjs";
7
8
  function prepareOctaneDocument(session, document, hydrating) {
8
9
  assertOctaneIdentity(session.identity);
9
10
  if ('node' !== session.platform.kind && 'worker' !== session.platform.kind) throw new Error('An Octane document requires a Node or worker request platform.');
@@ -74,12 +75,21 @@ async function renderOctaneApplication(input) {
74
75
  if (session.responsePolicy?.kind === 'terminal') return session.respond(null);
75
76
  session.startRendering();
76
77
  let head = '';
77
- const federation = input.federation ? createFederationScope(input.federation, true, document.nonce) : void 0;
78
+ const federation = input.federation || input.workerFederation ? createFederationScope(input.federation, true, document.nonce) : void 0;
78
79
  const App = federation ? ()=>createElement(FederationRoot, {
79
80
  scope: federation,
80
81
  children: 'function' == typeof input.App ? createElement(input.App, input.props) : input.App
81
82
  }) : input.App;
82
- const nativeStream = await renderToReadableStream(App, input.props, {
83
+ const workerFederation = input.workerFederation ? {
84
+ transport: input.workerFederation,
85
+ locale: input.workerFederationLocale ?? 'default',
86
+ signal: session.signal
87
+ } : void 0;
88
+ const NativeApp = workerFederation ? ()=>createElement(WorkerFederationRoot, {
89
+ scope: workerFederation,
90
+ children: 'function' == typeof App ? createElement(App, input.props) : App
91
+ }) : App;
92
+ const nativeStream = await renderToReadableStream(NativeApp, input.props, {
83
93
  signal: session.signal,
84
94
  ...void 0 === document.nonce ? {} : {
85
95
  nonce: document.nonce
@@ -92,6 +102,9 @@ async function renderOctaneApplication(input) {
92
102
  buildId: document.nativeHydrationBuildId,
93
103
  documentId: document.documentId
94
104
  },
105
+ externalSnapshots: {
106
+ documentId: document.documentId
107
+ },
95
108
  headChannel: 'separate',
96
109
  onHeadReady (value) {
97
110
  head = value;
@@ -0,0 +1,19 @@
1
+ import { createContext, createElement } from "octane";
2
+ import { FederationApplication } from "./federation-context.mjs";
3
+ const WorkerFederationContext = createContext(null);
4
+ function WorkerFederationRoot(props) {
5
+ return createElement(WorkerFederationContext, {
6
+ value: props.scope,
7
+ children: props.children
8
+ });
9
+ }
10
+ function WorkerFederationApplication(props) {
11
+ return createElement(WorkerFederationRoot, {
12
+ scope: props.scope,
13
+ children: props.federation ? createElement(FederationApplication, {
14
+ scope: props.federation,
15
+ application: props.application
16
+ }) : createElement(props.application.default, props.application.props)
17
+ });
18
+ }
19
+ export { WorkerFederationApplication, WorkerFederationContext, WorkerFederationRoot };
@@ -0,0 +1,47 @@
1
+ import { registerExternalSnapshotContext, useContext } from "octane";
2
+ const OCTANE_WORKER_CONTEXT_KEYS = Object.freeze({
3
+ router: 'ultramodern.octane.router-context.v1',
4
+ match: 'ultramodern.octane.match-context.v1',
5
+ i18n: 'ultramodern.octane.i18n-context.v1'
6
+ });
7
+ const builtinKeys = Object.values(OCTANE_WORKER_CONTEXT_KEYS);
8
+ const contexts = new Map();
9
+ function registerOctaneWorkerContext(context, codec) {
10
+ const { key, isProvided } = codec;
11
+ if (!builtinKeys.includes(key) || 'function' != typeof isProvided) throw new TypeError('Invalid Octane Worker builtin context codec');
12
+ const unregister = registerExternalSnapshotContext(context, codec);
13
+ const hasProvider = ()=>isProvided(useContext(context));
14
+ contexts.set(key, hasProvider);
15
+ return ()=>{
16
+ if (contexts.get(key) !== hasProvider) return;
17
+ unregister();
18
+ contexts.delete(key);
19
+ };
20
+ }
21
+ function useOctaneWorkerContextKeys(explicit = []) {
22
+ const selected = [];
23
+ for (const key of builtinKeys){
24
+ const hasProvider = contexts.get(key);
25
+ if (hasProvider?.() && !explicit.includes(key)) selected.push(key);
26
+ }
27
+ return [
28
+ ...selected,
29
+ ...explicit
30
+ ];
31
+ }
32
+ let routerRewrite;
33
+ function registerOctaneWorkerRouterRewrite(codec) {
34
+ if (routerRewrite || 'function' != typeof codec.capture || 'function' != typeof codec.restore) throw new TypeError('Invalid or duplicate Octane Worker router rewrite codec');
35
+ const captured = Object.freeze({
36
+ capture: codec.capture,
37
+ restore: codec.restore
38
+ });
39
+ routerRewrite = captured;
40
+ return ()=>{
41
+ if (routerRewrite === captured) routerRewrite = void 0;
42
+ };
43
+ }
44
+ function getOctaneWorkerRouterRewrite() {
45
+ return routerRewrite;
46
+ }
47
+ export { OCTANE_WORKER_CONTEXT_KEYS, getOctaneWorkerRouterRewrite, registerOctaneWorkerContext, registerOctaneWorkerRouterRewrite, useOctaneWorkerContextKeys };
@@ -0,0 +1,59 @@
1
+ import { createWorkerFederationTransport } from "@modern-js/renderer-core/worker-federation";
2
+ import { prepareExternalSnapshotRequest, releasePreparedExternalSnapshotRequest, renderExternalSnapshot, serializeExternalSnapshot } from "octane/server";
3
+ import { FederationContext, createFederationScope } from "./federation-context.mjs";
4
+ import { WorkerFederationContext } from "./worker-federation-context.mjs";
5
+ function isNativeWorkerComponent(value) {
6
+ return 'function' == typeof value;
7
+ }
8
+ function createNativeWorkerFederationRuntime(options, compiler) {
9
+ const { resources } = options;
10
+ const bindings = options.bindings;
11
+ const transport = resources.workerFederationServices?.length ? createWorkerFederationTransport({
12
+ admitRendererContract: compiler.admitRendererContract,
13
+ services: resources.workerFederationServices.map((service)=>{
14
+ const binding = bindings && Reflect.get(bindings, service.binding);
15
+ if (!binding || 'object' != typeof binding && 'function' != typeof binding || !('fetch' in binding) || 'function' != typeof binding.fetch) throw new Error(`Native Worker federation requires service binding ${service.binding}.`);
16
+ return {
17
+ ...service,
18
+ fetch: binding.fetch.bind(binding)
19
+ };
20
+ })
21
+ }) : void 0;
22
+ let handle;
23
+ if (resources.workerFederation) {
24
+ if (!compiler.registry || !resources.workerFederationManifestUrl) throw new Error('Native Worker federation requires its compiled expose registry and pinned manifest URL.');
25
+ handle = compiler.registry.initialize({
26
+ publication: resources.workerFederation.worker,
27
+ manifestUrl: resources.workerFederationManifestUrl,
28
+ admitRendererContract: compiler.admitRendererContract,
29
+ admitNativeRequest (payload, { admitted, signal }) {
30
+ const initializeContexts = transport ? (provide, request)=>{
31
+ provide(FederationContext, createFederationScope(void 0, true, request.nonce));
32
+ provide(WorkerFederationContext, {
33
+ transport,
34
+ locale: admitted.locale,
35
+ signal
36
+ });
37
+ } : void 0;
38
+ return prepareExternalSnapshotRequest(payload, {
39
+ authority: admitted.coordinate.native,
40
+ signal,
41
+ ...initializeContexts ? {
42
+ initializeContexts
43
+ } : {}
44
+ });
45
+ },
46
+ releaseNativeRequest: releasePreparedExternalSnapshotRequest,
47
+ async renderNativeSnapshot (module, request, { admitted }) {
48
+ const component = module && 'object' == typeof module && 'default' in module ? module.default : void 0;
49
+ if (!isNativeWorkerComponent(component)) throw new TypeError(`Native Worker expose ${admitted.expose} requires a default Octane component.`);
50
+ return serializeExternalSnapshot(await renderExternalSnapshot(component, request));
51
+ }
52
+ });
53
+ }
54
+ return {
55
+ transport,
56
+ handleRequest: handle ?? (()=>Promise.resolve(void 0))
57
+ };
58
+ }
59
+ export { createNativeWorkerFederationRuntime };
@@ -77,7 +77,7 @@ const rendererAdapter = defineRendererAdapter({
77
77
  create: {
78
78
  templates: {
79
79
  federation: true,
80
- workers: false
80
+ workers: true
81
81
  },
82
82
  dependencies: (profile, { typescriptVersion })=>({
83
83
  frameworkDependencies: [
@@ -22,7 +22,7 @@ const octaneProfile = {
22
22
  name: '@octanejs/tanstack-router',
23
23
  version: '0.2.10',
24
24
  coreName: '@tanstack/router-core',
25
- coreVersion: '1.171.34'
25
+ coreVersion: '1.171.38'
26
26
  },
27
27
  sourceExtensions: [
28
28
  '.tsx',
@@ -33,9 +33,10 @@ const octaneProfile = {
33
33
  jsxImportSource: 'octane',
34
34
  dependencies: {
35
35
  '@tsrx/oxc': '0.20.0',
36
- octane: 'https://github.com/BleedingDev/octane/releases/download/ultramodern-octane-d5988dd93614/octane-0.13.8.tgz',
37
- '@octanejs/tanstack-router': 'https://github.com/BleedingDev/octane/releases/download/ultramodern-octane-d5988dd93614/octanejs-tanstack-router-0.2.10.tgz',
38
- '@octanejs/rspack-plugin': 'https://github.com/BleedingDev/octane/releases/download/ultramodern-octane-d5988dd93614/octanejs-rspack-plugin-0.2.4.tgz',
36
+ octane: 'https://github.com/BleedingDev/octane/releases/download/ultramodern-octane-0bf2313bbdfb/octane-0.13.8.tgz',
37
+ '@octanejs/tanstack-router': 'https://github.com/BleedingDev/octane/releases/download/ultramodern-octane-0bf2313bbdfb/octanejs-tanstack-router-0.2.10.tgz',
38
+ '@octanejs/rspack-plugin': 'https://github.com/BleedingDev/octane/releases/download/ultramodern-octane-0bf2313bbdfb/octanejs-rspack-plugin-0.2.4.tgz',
39
+ '@tanstack/router-core': 'https://github.com/BleedingDev/router/releases/download/ultramodern-router-core-585d3233f7f5/tanstack-router-core-1.171.38.tgz',
39
40
  '@modern-js/renderer-octane': '3.8.3',
40
41
  seroval: '1.6.9',
41
42
  'seroval-plugins': '1.6.9'
@@ -1,6 +1,7 @@
1
1
  import type { NativeFederationBinding } from '@modern-js/renderer-core/federation';
2
2
  import { type RendererIdentity } from '@modern-js/renderer-core/identity';
3
3
  import { type ComponentBody, type Root, type RootContainer, type RootOptions } from 'octane';
4
+ import { type OctaneWorkerFederationFactory, type OctaneWorkerFederationScope } from './worker-federation-context';
4
5
  export type { OctaneDocumentBootstrap } from './bootstrap';
5
6
  export { readOctaneDocumentBootstrap } from './bootstrap';
6
7
  export interface OctaneApplicationModule {
@@ -23,9 +24,12 @@ export interface OctaneApplicationOptions {
23
24
  readonly signal?: AbortSignal;
24
25
  /** Hydration installs the native signal bridge before invoking this importer. */
25
26
  readonly load: () => Promise<OctaneApplicationModule>;
26
- readonly options?: Omit<RootOptions, 'signalOwner'>;
27
+ readonly options?: Omit<RootOptions, 'signalOwner' | 'externalSnapshots'>;
27
28
  /** This browser compilation's native Module Federation runtime. */
28
29
  readonly federation?: NativeFederationBinding;
30
+ readonly workerFederation?: OctaneWorkerFederationScope | OctaneWorkerFederationFactory;
31
+ /** Trusted document bootstrap identity, also present for a CSR document. */
32
+ readonly documentId?: string;
29
33
  }
30
34
  export interface OctaneHydrationOptions extends OctaneApplicationOptions {
31
35
  readonly documentIdentity: RendererIdentity;
@@ -1,8 +1,10 @@
1
1
  import type { LocalisedUrlsOption } from '@modern-js/i18n-runtime-extensions/paths';
2
2
  import { type NativeClientEntryOptions, type NativeI18nInstance } from '@modern-js/renderer-core/entry-client';
3
+ import type { OctaneWorkerFederationFactory, OctaneWorkerFederationScope } from './worker-federation-context';
3
4
  export interface OctaneClientEntryOptions extends NativeClientEntryOptions<NativeI18nInstance, LocalisedUrlsOption> {
4
5
  /** The native client compilation hash, `__webpack_hash__`. */
5
6
  readonly nativeHydrationBuildId: string;
7
+ readonly workerFederation?: OctaneWorkerFederationScope | OctaneWorkerFederationFactory;
6
8
  }
7
9
  /** Start a generated Octane browser entry: mount, or hydrate the server document. */
8
10
  export declare function startNativeClient(options: OctaneClientEntryOptions): void;
@@ -6,6 +6,9 @@ import type { ResponsePolicy } from '@modern-js/renderer-core/session';
6
6
  * declares for the document itself are kept, as Solid document headers are.
7
7
  */
8
8
  export declare function withOctaneDocumentFields(policy: ResponsePolicy, responseHeaders: Headers): ResponsePolicy;
9
- export type OctaneServerEntryOptions = NativeServerEntryOptions<NativeI18nInstance, LocalisedUrlsOption>;
9
+ export { createNativeWorkerFederationRuntime } from './worker-federation';
10
+ export interface OctaneServerEntryOptions extends NativeServerEntryOptions<NativeI18nInstance, LocalisedUrlsOption> {
11
+ readonly workerFederationLocale?: string;
12
+ }
10
13
  /** The native transport handlers of a generated Octane server entry. */
11
14
  export declare function createNativeServerEntry(options: OctaneServerEntryOptions): NativeServerEntry;
@@ -8,6 +8,8 @@ export interface FederatedComponentOptions {
8
8
  readonly fallback?: () => OctaneNode;
9
9
  /** A positive load limit; the server defaults to 3000ms. */
10
10
  readonly timeout?: number;
11
+ /** Explicit registered server projections required by an application remote. */
12
+ readonly contextKeys?: readonly string[];
11
13
  }
12
14
  /**
13
15
  * Render a native Octane remote by its `remote/Expose` id or a browser loader.
@@ -1,41 +1,14 @@
1
1
  import { type OctaneNode } from 'octane';
2
- import { type LinkComponentProps } from '../router';
3
- export interface LocalizedLinkProps {
2
+ import { type AnyRouter, type LinkComponentProps } from '../router';
3
+ export interface LocalizedLinkProps extends Omit<LinkComponentProps<'a', AnyRouter, string, string>, 'to' | 'mask' | 'href' | 'publicHref' | '_fromLocation'> {
4
4
  /** A canonical, language-agnostic target, e.g. `/products/red-shoe`. */
5
5
  to: string;
6
6
  /** Localize for a specific language instead of the current one. */
7
7
  language?: string;
8
- children?: unknown;
9
- class?: string;
10
- activeProps?: LinkComponentProps<'a'>['activeProps'];
11
- inactiveProps?: LinkComponentProps<'a'>['inactiveProps'];
12
- activeOptions?: LinkComponentProps<'a'>['activeOptions'];
13
- replace?: boolean;
14
- preload?: LinkComponentProps<'a'>['preload'];
15
8
  }
16
9
  /**
17
- * A thin wrapper over the native Octane router `Link`
18
- * (`@octanejs/tanstack-router`'s precompiled `Link.tsrx`) that localizes a
19
- * canonical `to` for the current (or an explicit) language before handing it
20
- * to the real link — the same contract as `@modern-js/plugin-i18n`'s React
21
- * `Link`. It resolves the href itself via the shared pathname helpers, so it
22
- * works with or without the router's i18n `rewrite`. Every link, including
23
- * one to another language, is the native `Link`: navigation, preloading and
24
- * active state stay with the router.
25
- *
26
- * Under the i18n `rewrite` the router matches canonical paths and localizes
27
- * outgoing locations to the current language, so a link to another language
28
- * routes to the canonical `to` and publishes the target language's URL as a
29
- * route mask (the rewrite keeps a mask's explicit language). The entry's
30
- * router language synchronization (`syncWithRouter`) switches the i18next
31
- * instance from the navigated URL, as it does for history navigation.
32
- *
33
- * No JSX: built with `createElement`, matching this package's existing
34
- * style (see `src/routes.ts`).
10
+ * The native router owns client navigation, preloading and active state. Its mask
11
+ * keeps the canonical route while publishing the selected language URL;
12
+ * the entry's i18n router subscription synchronizes the instance on navigation.
35
13
  */
36
14
  export declare function LocalizedLink(props: LocalizedLinkProps): OctaneNode;
37
- /**
38
- * Language-invariant active check: `to="/products"` is active whether the
39
- * current location is `/en/products` or `/produkty` under a mapped locale.
40
- */
41
- export declare function useIsLocalizedActive(canonicalTarget: string): boolean;
@@ -3,7 +3,7 @@ export type { I18nContextValue, I18nInstanceLike } from './types';
3
3
  /**
4
4
  * Octane's `createContext<T>(defaultValue: T)` requires a default (unlike
5
5
  * Solid 2's default-less form), so a missing provider is detected by
6
- * checking for `null` in `useI18n`/`useIsLocalizedActive` instead — the same
6
+ * checking for `null` in `useI18n`/`LocalizedLink` instead — the same
7
7
  * guard shape `@modern-js/plugin-i18n`'s React `ModernI18nContext` uses.
8
8
  */
9
9
  export declare const I18nContext: import("octane").Context<I18nContextValue | null>;
@@ -3,7 +3,7 @@ export { createI18nSsrHandoffInlineData, I18N_SSR_HANDOFF_ELEMENT_ID, type I18nS
3
3
  export { type CreateI18nUrlRewriteOptions, createI18nUrlRewrite, type I18nLocationRewrite, } from '@modern-js/i18n-runtime-extensions/urlRewrite';
4
4
  export { I18nContext } from './context';
5
5
  export { I18nProvider, type I18nProviderProps } from './I18nProvider';
6
- export { LocalizedLink, type LocalizedLinkProps, useIsLocalizedActive, } from './LocalizedLink';
6
+ export { LocalizedLink, type LocalizedLinkProps } from './LocalizedLink';
7
7
  export { type OctaneLatestLanguageSyncOptions, useLatestLanguageSync, } from './languageSync';
8
8
  export type { I18nContextValue, I18nInstanceLike } from './types';
9
9
  export { type UseI18nReturn, useI18n } from './useI18n';
@@ -0,0 +1,43 @@
1
+ import { type NativeI18nRewriteSnapshot } from '@modern-js/i18n-runtime-extensions/native';
2
+ import type { LocalisedUrlsOption } from '@modern-js/i18n-runtime-extensions/paths';
3
+ import type { NativeLocationRewrite } from '@modern-js/renderer-core/router';
4
+ import { type i18n as I18nInstance, type Resource } from 'i18next';
5
+ import type { I18nContextValue, I18nInstanceLike } from './i18n/types';
6
+ export type I18nSnapshotJson = null | boolean | number | string | I18nSnapshotJson[] | I18nSnapshotOptions;
7
+ export interface I18nSnapshotOptions {
8
+ [key: string]: I18nSnapshotJson;
9
+ }
10
+ export interface OctaneI18nProfileId {
11
+ key: string;
12
+ version: string;
13
+ }
14
+ export interface OctaneI18nSnapshot {
15
+ version: 1;
16
+ profile: OctaneI18nProfileId;
17
+ language: string;
18
+ languages: string[];
19
+ localisedUrls?: LocalisedUrlsOption;
20
+ options: I18nSnapshotOptions;
21
+ resources: Resource;
22
+ }
23
+ /** Named profiles install their custom translation functions locally. */
24
+ export interface OctaneI18nSnapshotProfile extends OctaneI18nProfileId {
25
+ captureOptions(instance: I18nInstanceLike): Readonly<I18nSnapshotOptions>;
26
+ validateOptions(options: Readonly<I18nSnapshotOptions>): void;
27
+ create(input: {
28
+ language: string;
29
+ options: Readonly<I18nSnapshotOptions>;
30
+ resources: Resource;
31
+ signal?: AbortSignal;
32
+ }): I18nInstance | Promise<I18nInstance>;
33
+ dispose?(instance: I18nInstance): void;
34
+ }
35
+ export declare function captureOctaneI18nRewriteSnapshot(rewrite: NativeLocationRewrite): NativeI18nRewriteSnapshot;
36
+ export declare function restoreOctaneI18nRewriteSnapshot(value: unknown): NativeLocationRewrite;
37
+ export declare function registerOctaneI18nSnapshotProfile(profile: OctaneI18nSnapshotProfile): () => void;
38
+ export declare function associateOctaneI18nSnapshotProfile(instance: I18nInstanceLike, id: OctaneI18nProfileId): void;
39
+ /** Built-in translation behavior only. Custom per-call processors need a profile. */
40
+ export declare function captureOctaneI18nSnapshot(value: I18nContextValue): OctaneI18nSnapshot;
41
+ export declare function restoreOctaneI18nSnapshot(value: unknown, signal?: AbortSignal): Promise<I18nContextValue>;
42
+ export declare function disposeOctaneI18nSnapshot(value: I18nContextValue): void;
43
+ export declare function registerOctaneI18nWorkerContexts(): () => void;
@@ -0,0 +1,10 @@
1
+ import { type AnyRouter, type RouterRenderSnapshot } from '@octanejs/tanstack-router';
2
+ export declare const OCTANE_FILE_ROUTE_SNAPSHOT_PROFILE: Readonly<{
3
+ key: "ultramodern.file-routes";
4
+ version: "1";
5
+ }>;
6
+ /** Associate the genuine router produced by the generated file-route factory. */
7
+ export declare function associateOctaneFileRouteSnapshot(router: AnyRouter): void;
8
+ export declare function captureOctaneRouterSnapshot(router: AnyRouter): RouterRenderSnapshot;
9
+ /** Startup registration uses the actual physical native router/match Contexts. */
10
+ export declare function registerOctaneRouterWorkerContexts(): () => void;
@@ -1,6 +1,7 @@
1
1
  import { type DocumentAsset, type DocumentInlineData } from '@modern-js/renderer-core/document';
2
2
  import type { NativeFederationBinding } from '@modern-js/renderer-core/federation';
3
3
  import { type RequestSession, type ResponsePolicy } from '@modern-js/renderer-core/session';
4
+ import type { WorkerFederationTransport } from '@modern-js/renderer-core/worker-federation';
4
5
  import type { AnyRouter } from '@octanejs/tanstack-router';
5
6
  import { type ServerRenderNode, type StreamOptions } from 'octane/server';
6
7
  export interface OctaneDocumentOptions {
@@ -32,6 +33,8 @@ export interface RenderOctaneApplicationOptions<Bindings extends object = object
32
33
  readonly routerSerializationTimeoutMs?: number;
33
34
  /** This server compilation's native Module Federation runtime. */
34
35
  readonly federation?: NativeFederationBinding;
36
+ readonly workerFederation?: WorkerFederationTransport;
37
+ readonly workerFederationLocale?: string;
35
38
  }
36
39
  /** Deliver the CSR document; native browser mounting owns the empty root. */
37
40
  export declare function renderOctaneCSRDocument<Bindings extends object>(input: OctaneDocumentResponseOptions<Bindings>): Promise<Response>;
@@ -0,0 +1,34 @@
1
+ import type { WorkerFederationTransport } from '@modern-js/renderer-core/worker-federation';
2
+ import { FederationApplication, type OctaneFederationScope } from './federation-context';
3
+ export interface OctaneWorkerFederationScope {
4
+ readonly transport: WorkerFederationTransport;
5
+ /** Compiled entry fallback; localized providers supply their live language. */
6
+ readonly locale: string;
7
+ /** Own document disposal; each lazy admission also owns its waiter deadline. */
8
+ readonly signal?: AbortSignal;
9
+ }
10
+ export type OctaneWorkerFederationFactory = (signal: AbortSignal) => OctaneWorkerFederationScope;
11
+ /** Each native document owns its transport and captured publisher authorities. */
12
+ export declare const WorkerFederationContext: import("octane").Context<OctaneWorkerFederationScope | null>;
13
+ export declare function WorkerFederationRoot(props: {
14
+ readonly scope: OctaneWorkerFederationScope;
15
+ readonly children?: unknown;
16
+ }): import("octane").ElementDescriptor<{
17
+ value: OctaneWorkerFederationScope;
18
+ children: unknown;
19
+ }>;
20
+ /** Stable native root used for startup and application updates alike. */
21
+ export declare function WorkerFederationApplication(props: {
22
+ readonly scope: OctaneWorkerFederationScope;
23
+ readonly federation?: OctaneFederationScope;
24
+ readonly application: Parameters<typeof FederationApplication>[0]['application'];
25
+ }): import("octane").ElementDescriptor<{
26
+ scope: OctaneWorkerFederationScope;
27
+ children: import("octane").ElementDescriptor<unknown> | import("octane").ElementDescriptor<{
28
+ scope: OctaneFederationScope;
29
+ application: {
30
+ readonly default: import("octane").ComponentBody;
31
+ readonly props?: unknown;
32
+ };
33
+ }>;
34
+ }>;