@bleedingdev/modern-js-renderer-octane 3.9.3-ultramodern.1 → 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.
Files changed (100) 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 +13 -5
  5. package/dist/cjs/federation.js +108 -6
  6. package/dist/cjs/i18n/I18nProvider.js +6 -14
  7. package/dist/cjs/i18n/LocalizedLink.js +24 -33
  8. package/dist/cjs/i18n/index.js +0 -3
  9. package/dist/cjs/i18n-external-snapshot.js +645 -0
  10. package/dist/cjs/index.js +4 -4
  11. package/dist/cjs/manifest.js +2 -2
  12. package/dist/cjs/plugin/compiler.js +2 -5
  13. package/dist/cjs/plugin/create.js +27 -26
  14. package/dist/cjs/plugin/index.js +2 -2
  15. package/dist/cjs/plugin/profile.js +12 -10
  16. package/dist/cjs/router-client.js +1 -1
  17. package/dist/cjs/router-external-snapshot.js +291 -0
  18. package/dist/cjs/router-handler.js +11 -8
  19. package/dist/cjs/router-server.js +3 -11
  20. package/dist/cjs/router.js +1 -1
  21. package/dist/cjs/routes.js +20 -17
  22. package/dist/cjs/server.js +28 -7
  23. package/dist/cjs/worker-federation-context.js +63 -0
  24. package/dist/cjs/worker-federation-contexts.js +97 -0
  25. package/dist/cjs/worker-federation.js +97 -0
  26. package/dist/esm/client.mjs +56 -6
  27. package/dist/esm/entry-application.mjs +7 -2
  28. package/dist/esm/entry-client.mjs +3 -0
  29. package/dist/esm/entry-server.mjs +11 -6
  30. package/dist/esm/federation.mjs +110 -8
  31. package/dist/esm/i18n/I18nProvider.mjs +7 -15
  32. package/dist/esm/i18n/LocalizedLink.mjs +24 -30
  33. package/dist/esm/i18n/index.mjs +1 -1
  34. package/dist/esm/i18n-external-snapshot.mjs +576 -0
  35. package/dist/esm/index.mjs +4 -4
  36. package/dist/esm/manifest.mjs +2 -2
  37. package/dist/esm/router-client.mjs +1 -1
  38. package/dist/esm/router-external-snapshot.mjs +244 -0
  39. package/dist/esm/router-handler.mjs +11 -8
  40. package/dist/esm/router-server.mjs +0 -1
  41. package/dist/esm/router.mjs +2 -2
  42. package/dist/esm/routes.mjs +18 -18
  43. package/dist/esm/server.mjs +24 -3
  44. package/dist/esm/worker-federation-context.mjs +19 -0
  45. package/dist/esm/worker-federation-contexts.mjs +47 -0
  46. package/dist/esm/worker-federation.mjs +59 -0
  47. package/dist/esm-node/manifest.mjs +2 -2
  48. package/dist/esm-node/plugin/compiler.mjs +2 -5
  49. package/dist/esm-node/plugin/create.mjs +27 -26
  50. package/dist/esm-node/plugin/index.mjs +2 -2
  51. package/dist/esm-node/plugin/profile.mjs +12 -10
  52. package/dist/types/client.d.ts +5 -1
  53. package/dist/types/entry-client.d.ts +2 -0
  54. package/dist/types/entry-server.d.ts +4 -1
  55. package/dist/types/federation.d.ts +2 -0
  56. package/dist/types/i18n/LocalizedLink.d.ts +5 -32
  57. package/dist/types/i18n/context.d.ts +1 -1
  58. package/dist/types/i18n/index.d.ts +1 -1
  59. package/dist/types/i18n-external-snapshot.d.ts +43 -0
  60. package/dist/types/index.d.ts +4 -4
  61. package/dist/types/manifest.d.ts +2 -2
  62. package/dist/types/router-external-snapshot.d.ts +10 -0
  63. package/dist/types/router-server.d.ts +0 -2
  64. package/dist/types/routes.d.ts +2 -0
  65. package/dist/types/server.d.ts +6 -0
  66. package/dist/types/worker-federation-context.d.ts +34 -0
  67. package/dist/types/worker-federation-contexts.d.ts +25 -0
  68. package/dist/types/worker-federation.d.ts +20 -0
  69. package/package.json +84 -22
  70. package/src/client.ts +99 -16
  71. package/src/entry-application.ts +7 -3
  72. package/src/entry-client.ts +10 -0
  73. package/src/entry-server.ts +20 -9
  74. package/src/federation.ts +164 -15
  75. package/src/i18n/I18nProvider.ts +11 -20
  76. package/src/i18n/LocalizedLink.ts +46 -72
  77. package/src/i18n/context.ts +1 -1
  78. package/src/i18n/index.ts +1 -5
  79. package/src/i18n-external-snapshot.ts +803 -0
  80. package/src/index.ts +4 -4
  81. package/src/manifest.ts +2 -2
  82. package/src/plugin/compiler-manifest.cjs +27 -1
  83. package/src/plugin/compiler.ts +6 -14
  84. package/src/plugin/create.ts +27 -26
  85. package/src/plugin/index.ts +4 -2
  86. package/src/plugin/profile.ts +14 -10
  87. package/src/router-client.ts +1 -1
  88. package/src/router-external-snapshot.ts +363 -0
  89. package/src/router-handler.ts +11 -8
  90. package/src/router-server.ts +0 -2
  91. package/src/router.ts +2 -2
  92. package/src/routes.ts +37 -26
  93. package/src/server.ts +45 -5
  94. package/src/worker-federation-context.ts +51 -0
  95. package/src/worker-federation-contexts.ts +91 -0
  96. package/src/worker-federation.ts +120 -0
  97. package/dist/cjs/router-injection.js +0 -139
  98. package/dist/esm/router-injection.mjs +0 -101
  99. package/dist/types/router-injection.d.ts +0 -8
  100. package/src/router-injection.ts +0 -145
@@ -30,6 +30,7 @@ __webpack_require__.r(__webpack_exports__);
30
30
  __webpack_require__.d(__webpack_exports__, {
31
31
  RouteDataError: ()=>router_namespaceObject.RouteDataError,
32
32
  createFileSystemRouteTree: ()=>createFileSystemRouteTree,
33
+ hasUnchangedOctaneFileRouteHead: ()=>hasUnchangedOctaneFileRouteHead,
33
34
  matchApplicationRouteIds: ()=>router_namespaceObject.matchApplicationRouteIds,
34
35
  matchApplicationRoutes: ()=>router_namespaceObject.matchApplicationRoutes,
35
36
  resolveRouteData: ()=>resolveRouteData,
@@ -38,6 +39,10 @@ __webpack_require__.d(__webpack_exports__, {
38
39
  const router_namespaceObject = require("@modern-js/renderer-core/router");
39
40
  const tanstack_router_namespaceObject = require("@octanejs/tanstack-router");
40
41
  const external_octane_namespaceObject = require("octane");
42
+ const fileRouteHeads = new WeakMap();
43
+ function hasUnchangedOctaneFileRouteHead(route) {
44
+ return fileRouteHeads.get(route) === route.options.head;
45
+ }
41
46
  function resolveRouteData(routeId, outcome) {
42
47
  return (0, router_namespaceObject.resolveRouteData)({
43
48
  redirect: tanstack_router_namespaceObject.redirect,
@@ -47,21 +52,12 @@ function resolveRouteData(routeId, outcome) {
47
52
  function isReactiveNativeMatch(value) {
48
53
  return 'object' == typeof value && null !== value && 'function' == typeof Reflect.get(value, 'get') && 'function' == typeof Reflect.get(value, 'subscribe');
49
54
  }
50
- function observeRouteCompletion(router, controller, signal, completion) {
55
+ function observeRouteCompletion(router, routeId, controller, signal, completion) {
51
56
  completion.catch((error)=>{
52
57
  if (signal.aborted) return;
53
- const match = [
54
- ...router.stores.pendingMatches.get(),
55
- ...router.stores.matches.get(),
56
- ...router.stores.cachedMatches.get()
57
- ].find((candidate)=>candidate.abortController === controller);
58
- if (!match) return;
59
- const store = [
60
- router.stores.pendingMatchStores.get(match.id),
61
- router.stores.matchStores.get(match.id),
62
- router.stores.cachedMatchStores.get(match.id)
63
- ].find((candidate)=>candidate?.get().abortController === controller);
64
- if (!store) return;
58
+ const route = Object.values(router.routesById).find((candidate)=>candidate.options.staticData?.ultramodernRouteId === routeId);
59
+ if (!route) return;
60
+ const store = router.stores.getMatchStore(route.id);
65
61
  let subscription;
66
62
  let settled = false;
67
63
  const cleanup = ()=>{
@@ -72,9 +68,10 @@ function observeRouteCompletion(router, controller, signal, completion) {
72
68
  settled = true;
73
69
  cleanup();
74
70
  };
75
- const publish = ()=>{
71
+ const publish = async ()=>{
76
72
  if (settled) return;
77
73
  const current = store.get();
74
+ if (!current) return;
78
75
  if (current.abortController !== controller || signal.aborted || 'pending' !== current.status && 'success' !== current.status) return void onAbort();
79
76
  if ('success' !== current.status || current.isFetching) return;
80
77
  settled = true;
@@ -82,17 +79,19 @@ function observeRouteCompletion(router, controller, signal, completion) {
82
79
  const route = router.routesById[current.routeId];
83
80
  let failure = error;
84
81
  try {
82
+ await route?.options.errorComponent?.preload?.();
83
+ if (signal.aborted || store.get()?.abortController !== controller) return;
85
84
  route?.options.onError?.(failure);
86
85
  } catch (onErrorFailure) {
87
86
  failure = onErrorFailure;
88
87
  }
89
88
  if (signal.aborted) return;
90
- router.updateMatch(match.id, (previous)=>previous.abortController !== controller || 'success' !== previous.status || previous.isFetching ? previous : {
89
+ router.stores.setMatches(router.stores.matches.get().map((previous)=>previous.routeId !== route.id || previous.abortController !== controller || 'success' !== previous.status || previous.isFetching ? previous : {
91
90
  ...previous,
92
91
  error: failure,
93
92
  status: 'error',
94
93
  isFetching: false
95
- });
94
+ }));
96
95
  };
97
96
  signal.addEventListener('abort', onAbort, {
98
97
  once: true
@@ -136,7 +135,7 @@ function createFileSystemRouteTree(routes, modules, options = {}) {
136
135
  await Promise.resolve();
137
136
  signal.throwIfAborted();
138
137
  if (failed) throw failure;
139
- observeRouteCompletion(router, match.abortController, signal, outcome.completion);
138
+ observeRouteCompletion(router, route.id, match.abortController, signal, outcome.completion);
140
139
  }
141
140
  options.onOutcome?.(route.id, outcome);
142
141
  return resolveRouteData(route.id, outcome);
@@ -157,6 +156,7 @@ function createFileSystemRouteTree(routes, modules, options = {}) {
157
156
  ...rootBindings,
158
157
  component: OctaneDocumentRoot
159
158
  });
159
+ fileRouteHeads.set(root, root.options.head);
160
160
  function bind(route, parent, inheritedErrorComponent) {
161
161
  const errorComponent = modules[route.id]?.errorComponent ?? inheritedErrorComponent;
162
162
  const native = (0, tanstack_router_namespaceObject.createRoute)({
@@ -164,12 +164,14 @@ function createFileSystemRouteTree(routes, modules, options = {}) {
164
164
  ...(0, router_namespaceObject.nativeRoutePath)(route),
165
165
  ...bindings(route, errorComponent)
166
166
  });
167
+ fileRouteHeads.set(native, native.options.head);
167
168
  return native.addChildren(route.children.map((child)=>bind(child, native, errorComponent)));
168
169
  }
169
170
  return root.addChildren(children.map((route)=>bind(route, root, rootErrorComponent)));
170
171
  }
171
172
  exports.RouteDataError = __webpack_exports__.RouteDataError;
172
173
  exports.createFileSystemRouteTree = __webpack_exports__.createFileSystemRouteTree;
174
+ exports.hasUnchangedOctaneFileRouteHead = __webpack_exports__.hasUnchangedOctaneFileRouteHead;
173
175
  exports.matchApplicationRouteIds = __webpack_exports__.matchApplicationRouteIds;
174
176
  exports.matchApplicationRoutes = __webpack_exports__.matchApplicationRoutes;
175
177
  exports.resolveRouteData = __webpack_exports__.resolveRouteData;
@@ -177,6 +179,7 @@ exports.selectApplicationDataRoute = __webpack_exports__.selectApplicationDataRo
177
179
  for(var __rspack_i in __webpack_exports__)if (-1 === [
178
180
  "RouteDataError",
179
181
  "createFileSystemRouteTree",
182
+ "hasUnchangedOctaneFileRouteHead",
180
183
  "matchApplicationRouteIds",
181
184
  "matchApplicationRoutes",
182
185
  "resolveRouteData",
@@ -33,9 +33,11 @@ __webpack_require__.d(__webpack_exports__, {
33
33
  });
34
34
  const document_namespaceObject = require("@modern-js/renderer-core/document");
35
35
  const session_namespaceObject = require("@modern-js/renderer-core/session");
36
- const server_namespaceObject = require("octane/server");
36
+ const server_namespaceObject = require("@octanejs/tanstack-router/ssr/server");
37
+ const external_octane_server_namespaceObject = require("octane/server");
37
38
  const external_bootstrap_js_namespaceObject = require("./bootstrap.js");
38
39
  const external_federation_context_js_namespaceObject = require("./federation-context.js");
40
+ const external_worker_federation_context_js_namespaceObject = require("./worker-federation-context.js");
39
41
  function prepareOctaneDocument(session, document, hydrating) {
40
42
  (0, external_bootstrap_js_namespaceObject.assertOctaneIdentity)(session.identity);
41
43
  if ('node' !== session.platform.kind && 'worker' !== session.platform.kind) throw new Error('An Octane document requires a Node or worker request platform.');
@@ -99,19 +101,28 @@ async function renderOctaneApplication(input) {
99
101
  const { session, document } = input;
100
102
  try {
101
103
  const { rootId, lang, bootstrap, headAssets, entryScripts } = prepareOctaneDocument(session, document, true);
102
- const earlyBootstrap = (0, server_namespaceObject.earlySignalBootstrapScript)(void 0 === document.nonce ? {} : {
104
+ const earlyBootstrap = (0, external_octane_server_namespaceObject.earlySignalBootstrapScript)(void 0 === document.nonce ? {} : {
103
105
  nonce: document.nonce
104
106
  });
105
107
  await resolveDocumentResponse(input);
106
108
  if (session.responsePolicy?.kind === 'terminal') return session.respond(null);
107
109
  session.startRendering();
108
110
  let head = '';
109
- const federation = input.federation ? (0, external_federation_context_js_namespaceObject.createFederationScope)(input.federation, true, document.nonce) : void 0;
110
- const App = federation ? ()=>(0, server_namespaceObject.createElement)(external_federation_context_js_namespaceObject.FederationRoot, {
111
+ const federation = input.federation || input.workerFederation ? (0, external_federation_context_js_namespaceObject.createFederationScope)(input.federation, true, document.nonce) : void 0;
112
+ const App = federation ? ()=>(0, external_octane_server_namespaceObject.createElement)(external_federation_context_js_namespaceObject.FederationRoot, {
111
113
  scope: federation,
112
- children: 'function' == typeof input.App ? (0, server_namespaceObject.createElement)(input.App, input.props) : input.App
114
+ children: 'function' == typeof input.App ? (0, external_octane_server_namespaceObject.createElement)(input.App, input.props) : input.App
113
115
  }) : input.App;
114
- const nativeStream = await (0, server_namespaceObject.renderToReadableStream)(App, input.props, {
116
+ const workerFederation = input.workerFederation ? {
117
+ transport: input.workerFederation,
118
+ locale: input.workerFederationLocale ?? 'default',
119
+ signal: session.signal
120
+ } : void 0;
121
+ const NativeApp = workerFederation ? ()=>(0, external_octane_server_namespaceObject.createElement)(external_worker_federation_context_js_namespaceObject.WorkerFederationRoot, {
122
+ scope: workerFederation,
123
+ children: 'function' == typeof App ? (0, external_octane_server_namespaceObject.createElement)(App, input.props) : App
124
+ }) : App;
125
+ const nativeStream = await (0, external_octane_server_namespaceObject.renderToReadableStream)(NativeApp, input.props, {
115
126
  signal: session.signal,
116
127
  ...void 0 === document.nonce ? {} : {
117
128
  nonce: document.nonce
@@ -124,6 +135,9 @@ async function renderOctaneApplication(input) {
124
135
  buildId: document.nativeHydrationBuildId,
125
136
  documentId: document.documentId
126
137
  },
138
+ externalSnapshots: {
139
+ documentId: document.documentId
140
+ },
127
141
  headChannel: 'separate',
128
142
  onHeadReady (value) {
129
143
  head = value;
@@ -207,7 +221,14 @@ async function renderOctaneApplication(input) {
207
221
  }, {
208
222
  highWaterMark: 0
209
223
  });
210
- return session.respond(body);
224
+ return session.respond(input.router ? (0, server_namespaceObject.transformReadableStreamWithRouter)(input.router, body, {
225
+ signal: session.signal,
226
+ rendererSafePoint: "script-close",
227
+ timeoutMs: input.routerSerializationTimeoutMs,
228
+ onAbort: (reason)=>{
229
+ session.fail(reason);
230
+ }
231
+ }) : body);
211
232
  } catch (error) {
212
233
  await session.fail(error);
213
234
  throw error;
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, getters, values)=>{
5
+ var define = (defs, kind)=>{
6
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
7
+ enumerable: true,
8
+ [kind]: defs[key]
9
+ });
10
+ };
11
+ define(getters, "get");
12
+ define(values, "value");
13
+ };
14
+ })();
15
+ (()=>{
16
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
17
+ })();
18
+ (()=>{
19
+ __webpack_require__.r = (exports1)=>{
20
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
21
+ value: 'Module'
22
+ });
23
+ Object.defineProperty(exports1, '__esModule', {
24
+ value: true
25
+ });
26
+ };
27
+ })();
28
+ var __webpack_exports__ = {};
29
+ __webpack_require__.r(__webpack_exports__);
30
+ __webpack_require__.d(__webpack_exports__, {
31
+ WorkerFederationApplication: ()=>WorkerFederationApplication,
32
+ WorkerFederationContext: ()=>WorkerFederationContext,
33
+ WorkerFederationRoot: ()=>WorkerFederationRoot
34
+ });
35
+ const external_octane_namespaceObject = require("octane");
36
+ const external_federation_context_js_namespaceObject = require("./federation-context.js");
37
+ const WorkerFederationContext = (0, external_octane_namespaceObject.createContext)(null);
38
+ function WorkerFederationRoot(props) {
39
+ return (0, external_octane_namespaceObject.createElement)(WorkerFederationContext, {
40
+ value: props.scope,
41
+ children: props.children
42
+ });
43
+ }
44
+ function WorkerFederationApplication(props) {
45
+ return (0, external_octane_namespaceObject.createElement)(WorkerFederationRoot, {
46
+ scope: props.scope,
47
+ children: props.federation ? (0, external_octane_namespaceObject.createElement)(external_federation_context_js_namespaceObject.FederationApplication, {
48
+ scope: props.federation,
49
+ application: props.application
50
+ }) : (0, external_octane_namespaceObject.createElement)(props.application.default, props.application.props)
51
+ });
52
+ }
53
+ exports.WorkerFederationApplication = __webpack_exports__.WorkerFederationApplication;
54
+ exports.WorkerFederationContext = __webpack_exports__.WorkerFederationContext;
55
+ exports.WorkerFederationRoot = __webpack_exports__.WorkerFederationRoot;
56
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
57
+ "WorkerFederationApplication",
58
+ "WorkerFederationContext",
59
+ "WorkerFederationRoot"
60
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
61
+ Object.defineProperty(exports, '__esModule', {
62
+ value: true
63
+ });
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, getters, values)=>{
5
+ var define = (defs, kind)=>{
6
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
7
+ enumerable: true,
8
+ [kind]: defs[key]
9
+ });
10
+ };
11
+ define(getters, "get");
12
+ define(values, "value");
13
+ };
14
+ })();
15
+ (()=>{
16
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
17
+ })();
18
+ (()=>{
19
+ __webpack_require__.r = (exports1)=>{
20
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
21
+ value: 'Module'
22
+ });
23
+ Object.defineProperty(exports1, '__esModule', {
24
+ value: true
25
+ });
26
+ };
27
+ })();
28
+ var __webpack_exports__ = {};
29
+ __webpack_require__.r(__webpack_exports__);
30
+ __webpack_require__.d(__webpack_exports__, {
31
+ OCTANE_WORKER_CONTEXT_KEYS: ()=>OCTANE_WORKER_CONTEXT_KEYS,
32
+ getOctaneWorkerRouterRewrite: ()=>getOctaneWorkerRouterRewrite,
33
+ registerOctaneWorkerContext: ()=>registerOctaneWorkerContext,
34
+ registerOctaneWorkerRouterRewrite: ()=>registerOctaneWorkerRouterRewrite,
35
+ useOctaneWorkerContextKeys: ()=>useOctaneWorkerContextKeys
36
+ });
37
+ const external_octane_namespaceObject = require("octane");
38
+ const OCTANE_WORKER_CONTEXT_KEYS = Object.freeze({
39
+ router: 'ultramodern.octane.router-context.v1',
40
+ match: 'ultramodern.octane.match-context.v1',
41
+ i18n: 'ultramodern.octane.i18n-context.v1'
42
+ });
43
+ const builtinKeys = Object.values(OCTANE_WORKER_CONTEXT_KEYS);
44
+ const contexts = new Map();
45
+ function registerOctaneWorkerContext(context, codec) {
46
+ const { key, isProvided } = codec;
47
+ if (!builtinKeys.includes(key) || 'function' != typeof isProvided) throw new TypeError('Invalid Octane Worker builtin context codec');
48
+ const unregister = (0, external_octane_namespaceObject.registerExternalSnapshotContext)(context, codec);
49
+ const hasProvider = ()=>isProvided((0, external_octane_namespaceObject.useContext)(context));
50
+ contexts.set(key, hasProvider);
51
+ return ()=>{
52
+ if (contexts.get(key) !== hasProvider) return;
53
+ unregister();
54
+ contexts.delete(key);
55
+ };
56
+ }
57
+ function useOctaneWorkerContextKeys(explicit = []) {
58
+ const selected = [];
59
+ for (const key of builtinKeys){
60
+ const hasProvider = contexts.get(key);
61
+ if (hasProvider?.() && !explicit.includes(key)) selected.push(key);
62
+ }
63
+ return [
64
+ ...selected,
65
+ ...explicit
66
+ ];
67
+ }
68
+ let routerRewrite;
69
+ function registerOctaneWorkerRouterRewrite(codec) {
70
+ if (routerRewrite || 'function' != typeof codec.capture || 'function' != typeof codec.restore) throw new TypeError('Invalid or duplicate Octane Worker router rewrite codec');
71
+ const captured = Object.freeze({
72
+ capture: codec.capture,
73
+ restore: codec.restore
74
+ });
75
+ routerRewrite = captured;
76
+ return ()=>{
77
+ if (routerRewrite === captured) routerRewrite = void 0;
78
+ };
79
+ }
80
+ function getOctaneWorkerRouterRewrite() {
81
+ return routerRewrite;
82
+ }
83
+ exports.OCTANE_WORKER_CONTEXT_KEYS = __webpack_exports__.OCTANE_WORKER_CONTEXT_KEYS;
84
+ exports.getOctaneWorkerRouterRewrite = __webpack_exports__.getOctaneWorkerRouterRewrite;
85
+ exports.registerOctaneWorkerContext = __webpack_exports__.registerOctaneWorkerContext;
86
+ exports.registerOctaneWorkerRouterRewrite = __webpack_exports__.registerOctaneWorkerRouterRewrite;
87
+ exports.useOctaneWorkerContextKeys = __webpack_exports__.useOctaneWorkerContextKeys;
88
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
89
+ "OCTANE_WORKER_CONTEXT_KEYS",
90
+ "getOctaneWorkerRouterRewrite",
91
+ "registerOctaneWorkerContext",
92
+ "registerOctaneWorkerRouterRewrite",
93
+ "useOctaneWorkerContextKeys"
94
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
95
+ Object.defineProperty(exports, '__esModule', {
96
+ value: true
97
+ });
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, getters, values)=>{
5
+ var define = (defs, kind)=>{
6
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
7
+ enumerable: true,
8
+ [kind]: defs[key]
9
+ });
10
+ };
11
+ define(getters, "get");
12
+ define(values, "value");
13
+ };
14
+ })();
15
+ (()=>{
16
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
17
+ })();
18
+ (()=>{
19
+ __webpack_require__.r = (exports1)=>{
20
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
21
+ value: 'Module'
22
+ });
23
+ Object.defineProperty(exports1, '__esModule', {
24
+ value: true
25
+ });
26
+ };
27
+ })();
28
+ var __webpack_exports__ = {};
29
+ __webpack_require__.r(__webpack_exports__);
30
+ __webpack_require__.d(__webpack_exports__, {
31
+ createNativeWorkerFederationRuntime: ()=>createNativeWorkerFederationRuntime
32
+ });
33
+ const worker_federation_namespaceObject = require("@modern-js/renderer-core/worker-federation");
34
+ const server_namespaceObject = require("octane/server");
35
+ const external_federation_context_js_namespaceObject = require("./federation-context.js");
36
+ const external_worker_federation_context_js_namespaceObject = require("./worker-federation-context.js");
37
+ function isNativeWorkerComponent(value) {
38
+ return 'function' == typeof value;
39
+ }
40
+ function createNativeWorkerFederationRuntime(options, compiler) {
41
+ const { resources } = options;
42
+ const bindings = options.bindings;
43
+ const transport = resources.workerFederationServices?.length ? (0, worker_federation_namespaceObject.createWorkerFederationTransport)({
44
+ admitRendererContract: compiler.admitRendererContract,
45
+ services: resources.workerFederationServices.map((service)=>{
46
+ const binding = bindings && Reflect.get(bindings, service.binding);
47
+ 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}.`);
48
+ return {
49
+ ...service,
50
+ fetch: binding.fetch.bind(binding)
51
+ };
52
+ })
53
+ }) : void 0;
54
+ let handle;
55
+ if (resources.workerFederation) {
56
+ if (!compiler.registry || !resources.workerFederationManifestUrl) throw new Error('Native Worker federation requires its compiled expose registry and pinned manifest URL.');
57
+ handle = compiler.registry.initialize({
58
+ publication: resources.workerFederation.worker,
59
+ manifestUrl: resources.workerFederationManifestUrl,
60
+ admitRendererContract: compiler.admitRendererContract,
61
+ admitNativeRequest (payload, { admitted, signal }) {
62
+ const initializeContexts = transport ? (provide, request)=>{
63
+ provide(external_federation_context_js_namespaceObject.FederationContext, (0, external_federation_context_js_namespaceObject.createFederationScope)(void 0, true, request.nonce));
64
+ provide(external_worker_federation_context_js_namespaceObject.WorkerFederationContext, {
65
+ transport,
66
+ locale: admitted.locale,
67
+ signal
68
+ });
69
+ } : void 0;
70
+ return (0, server_namespaceObject.prepareExternalSnapshotRequest)(payload, {
71
+ authority: admitted.coordinate.native,
72
+ signal,
73
+ ...initializeContexts ? {
74
+ initializeContexts
75
+ } : {}
76
+ });
77
+ },
78
+ releaseNativeRequest: server_namespaceObject.releasePreparedExternalSnapshotRequest,
79
+ async renderNativeSnapshot (module, request, { admitted }) {
80
+ const component = module && 'object' == typeof module && 'default' in module ? module.default : void 0;
81
+ if (!isNativeWorkerComponent(component)) throw new TypeError(`Native Worker expose ${admitted.expose} requires a default Octane component.`);
82
+ return (0, server_namespaceObject.serializeExternalSnapshot)(await (0, server_namespaceObject.renderExternalSnapshot)(component, request));
83
+ }
84
+ });
85
+ }
86
+ return {
87
+ transport,
88
+ handleRequest: handle ?? (()=>Promise.resolve(void 0))
89
+ };
90
+ }
91
+ exports.createNativeWorkerFederationRuntime = __webpack_exports__.createNativeWorkerFederationRuntime;
92
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
93
+ "createNativeWorkerFederationRuntime"
94
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
95
+ Object.defineProperty(exports, '__esModule', {
96
+ value: true
97
+ });
@@ -3,6 +3,7 @@ import { createRoot, hydrateRoot } from "octane";
3
3
  import { bootstrapStreamedSignalHydration } from "octane/hydration/streamed-signals";
4
4
  import { assertNativeHydrationBuildId, assertOctaneIdentity, readOctaneDocumentBootstrap } from "./bootstrap.mjs";
5
5
  import { FederationApplication, createFederationScope } from "./federation-context.mjs";
6
+ import { WorkerFederationApplication } from "./worker-federation-context.mjs";
6
7
  const roots = new WeakMap();
7
8
  const documents = new WeakMap();
8
9
  const moduleResources = new WeakMap();
@@ -186,7 +187,11 @@ function createHandle(input) {
186
187
  const nextRelease = claimModuleResources(next);
187
188
  releaseModule = nextRelease;
188
189
  try {
189
- input.federation ? input.root.render(FederationApplication, {
190
+ input.workerFederation ? input.root.render(WorkerFederationApplication, {
191
+ scope: input.workerFederation,
192
+ federation: input.federation,
193
+ application: next
194
+ }) : input.federation ? input.root.render(FederationApplication, {
190
195
  scope: input.federation,
191
196
  application: next
192
197
  }) : input.root.render(next.default, next.props);
@@ -204,6 +209,7 @@ function createHandle(input) {
204
209
  disposed = true;
205
210
  input.signal?.removeEventListener('abort', onAbort);
206
211
  cleanupResources([
212
+ ()=>input.retireWorkerFederation?.(),
207
213
  ()=>input.root.unmount(),
208
214
  ()=>releaseModule(),
209
215
  ()=>input.bridge?.dispose(),
@@ -227,6 +233,12 @@ function createHandle(input) {
227
233
  }
228
234
  async function startApplication(input, release, hydration) {
229
235
  const errors = observeRootErrors(input.options);
236
+ const workerController = input.workerFederation ? new AbortController() : void 0;
237
+ let workerFederation;
238
+ const retireWorkerFederation = ()=>cleanupResources([
239
+ ()=>workerController?.abort(new DOMException('The Worker federation document was disposed', 'AbortError')),
240
+ ()=>workerFederation?.transport.dispose()
241
+ ]);
230
242
  let bridge;
231
243
  let root;
232
244
  let releaseModule;
@@ -237,6 +249,7 @@ async function startApplication(input, release, hydration) {
237
249
  if (cleaned) return;
238
250
  cleaned = true;
239
251
  cleanupResources([
252
+ retireWorkerFederation,
240
253
  ()=>root?.unmount(),
241
254
  ()=>releaseModule?.(),
242
255
  ()=>bridge?.dispose(),
@@ -244,7 +257,24 @@ async function startApplication(input, release, hydration) {
244
257
  ]);
245
258
  };
246
259
  try {
247
- const federation = input.federation ? createFederationScope(input.federation, false) : void 0;
260
+ if (input.workerFederation && workerController) {
261
+ const signal = AbortSignal.any([
262
+ workerController.signal,
263
+ ...input.signal ? [
264
+ input.signal
265
+ ] : []
266
+ ]);
267
+ const scope = 'function' == typeof input.workerFederation ? input.workerFederation(signal) : input.workerFederation;
268
+ workerFederation = {
269
+ ...scope,
270
+ signal: scope.signal ? AbortSignal.any([
271
+ signal,
272
+ scope.signal
273
+ ]) : signal
274
+ };
275
+ }
276
+ if (workerFederation && !hydration && !input.documentId) throw new Error('Worker federation requires the trusted document identity before application loading');
277
+ const federation = input.federation || workerFederation ? createFederationScope(input.federation, false) : void 0;
248
278
  if (hydration) {
249
279
  const { document, documentId } = hydration;
250
280
  bridge = bootstrapStreamedSignalHydration({
@@ -259,16 +289,34 @@ async function startApplication(input, release, hydration) {
259
289
  const application = loaded.application;
260
290
  releaseModule = loaded.releaseModule;
261
291
  input.signal?.throwIfAborted();
262
- if (bridge) root = hydrateRoot(input.container, federation ? FederationApplication : application.default, federation ? {
292
+ if (bridge) root = hydrateRoot(input.container, workerFederation ? WorkerFederationApplication : federation ? FederationApplication : application.default, workerFederation ? {
293
+ scope: workerFederation,
294
+ federation,
295
+ application
296
+ } : federation ? {
263
297
  scope: federation,
264
298
  application
265
299
  } : application.props, {
266
300
  ...errors.options,
267
- signalOwner: bridge.signalOwner
301
+ signalOwner: bridge.signalOwner,
302
+ externalSnapshots: {
303
+ documentId: hydration.documentId
304
+ }
268
305
  });
269
306
  else {
270
- root = createRoot(input.container, errors.options);
271
- federation ? root.render(FederationApplication, {
307
+ root = createRoot(input.container, {
308
+ ...errors.options,
309
+ ...input.documentId ? {
310
+ externalSnapshots: {
311
+ documentId: input.documentId
312
+ }
313
+ } : {}
314
+ });
315
+ workerFederation ? root.render(WorkerFederationApplication, {
316
+ scope: workerFederation,
317
+ federation,
318
+ application
319
+ }) : federation ? root.render(FederationApplication, {
272
320
  scope: federation,
273
321
  application
274
322
  }) : root.render(application.default, application.props);
@@ -282,6 +330,8 @@ async function startApplication(input, release, hydration) {
282
330
  release,
283
331
  bridge,
284
332
  federation,
333
+ workerFederation,
334
+ retireWorkerFederation,
285
335
  ...void 0 === input.signal ? {} : {
286
336
  signal: input.signal
287
337
  },
@@ -1,6 +1,7 @@
1
1
  import { createMemoryHistory, createRouter } from "@octanejs/tanstack-router";
2
2
  import { createElement } from "octane";
3
3
  import { I18nProvider } from "./i18n/I18nProvider.mjs";
4
+ import { associateOctaneFileRouteSnapshot } from "./router-external-snapshot.mjs";
4
5
  import { createFileSystemRouteTree } from "./routes.mjs";
5
6
  function componentView(component, i18n) {
6
7
  const App = component;
@@ -14,7 +15,8 @@ function componentView(component, i18n) {
14
15
  }
15
16
  const octaneRouterFactory = {
16
17
  routeTree: (routes, modules, options)=>createFileSystemRouteTree(routes, modules, options),
17
- router: ({ location, ...options })=>createRouter({
18
+ router: ({ location, ...options })=>{
19
+ const router = createRouter({
18
20
  ...options,
19
21
  ...location ? {
20
22
  origin: location.origin,
@@ -24,7 +26,10 @@ const octaneRouterFactory = {
24
26
  ]
25
27
  })
26
28
  } : {}
27
- })
29
+ });
30
+ associateOctaneFileRouteSnapshot(router);
31
+ return router;
32
+ }
28
33
  };
29
34
  function localizedRouterRoot(Root) {
30
35
  return ({ router, i18n })=>createElement(I18nProvider, {
@@ -9,6 +9,7 @@ function startNativeClient(options) {
9
9
  startNativeClientEntry(options, {
10
10
  readBootstrap: (document, identity)=>readOctaneDocumentBootstrap(document, identity, nativeHydrationBuildId),
11
11
  createRouter: (application, routerOptions)=>createNativeRouter(application, routerOptions, octaneRouterFactory),
12
+ disposeRouter: (router)=>router.history.destroy(),
12
13
  async prepareRouter (router, hydrating, signal) {
13
14
  if (hydrating) await prepareOctaneRouterHydration(router, {
14
15
  signal
@@ -21,6 +22,8 @@ function startNativeClient(options) {
21
22
  identity,
22
23
  nativeHydrationBuildId,
23
24
  federation: options.federation,
25
+ workerFederation: options.workerFederation,
26
+ documentId: bootstrap?.documentId,
24
27
  signal,
25
28
  load: async ()=>{
26
29
  const view = await load();