@foxford/den 3.2.1 → 3.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.mdx +35 -0
- package/bin/den.cjs +3 -3
- package/bin/den.js +1 -1
- package/builder/index.cjs +2 -2
- package/builder/index.d.cts +8 -3
- package/builder/index.d.ts +8 -3
- package/builder/index.js +1 -1
- package/{chunk-UB3GCX73.cjs → chunk-3X4WVHUU.cjs} +30 -13
- package/{chunk-TPHJUDHG.js → chunk-SOH2TL2N.js} +35 -20
- package/{chunk-ZOU6W6ZQ.cjs → chunk-XDM6J4LJ.cjs} +35 -20
- package/{chunk-URSWYSZF.js → chunk-XU5HUIPK.js} +30 -13
- package/{descriptor-Dujg_1on.d.cts → descriptor-BfsBDME1.d.cts} +16 -6
- package/{descriptor-DQ6Gi7A_.d.ts → descriptor-D8ocBnTb.d.ts} +16 -6
- package/index.d.cts +2 -2
- package/index.d.ts +2 -2
- package/island/index.cjs +2 -2
- package/island/index.d.cts +13 -6
- package/island/index.d.ts +13 -6
- package/island/index.js +1 -1
- package/package.json +10 -10
- package/serve/index.cjs +4 -4
- package/serve/index.d.cts +1 -1
- package/serve/index.d.ts +1 -1
- package/serve/index.js +1 -1
- package/{view-adapter-B4gEb-ms.d.ts → view-adapter-Bzcjotsn.d.ts} +1 -1
- package/{view-adapter-DJ7yB6Ml.d.cts → view-adapter-Cia9blgH.d.cts} +1 -1
package/README.mdx
CHANGED
|
@@ -125,6 +125,41 @@ export class ContentPageVM extends ViewModel<State> {
|
|
|
125
125
|
|
|
126
126
|
Редирект объявляется там же: `{ redirect: '/user/login' }` — без статуса это `302`.
|
|
127
127
|
|
|
128
|
+
### Приложение без рендера
|
|
129
|
+
|
|
130
|
+
`view` и `viewLayer` объявляются парой либо не объявляются вовсе. Приложение без них сообщает
|
|
131
|
+
документу данные, а свой кусок страницы рисует кто-то другой — например, клиент монолита.
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
export default {
|
|
135
|
+
name: 'spa-portal',
|
|
136
|
+
units: [],
|
|
137
|
+
viewModels: [shellVm], // describeDocument отдаёт данные документа и артефакты адреса
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
describeDocument(): DocumentContribution {
|
|
143
|
+
const { shell } = this.state.get()
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
// состав знает шаблон документа хоста, ядру перечислять его нечем
|
|
147
|
+
data: { containerId: shell.containerId, manifest: shell.manifest },
|
|
148
|
+
// чанки зависят от адреса, поэтому их знает рендер, а не сборка
|
|
149
|
+
assets: { css: shell.css, js: shell.js, scripts: 'classic' },
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Жизненный цикл у такого приложения тот же — контейнер, единицы, активация VM, вклад в документ, —
|
|
155
|
+
укорачивается ровно отрисовка: `html` в ответе пустой, `state` посчитан как обычно. `den build`
|
|
156
|
+
собирает его так же: `den.config.ts` без пресета означает, что клиентского выхода не бывает,
|
|
157
|
+
и остаются серверный дескриптор с точкой входа процесса.
|
|
158
|
+
|
|
159
|
+
`scripts: 'classic'` нужен там, где чанки собраны не ES-модулями: вид скрипта знает сборка, а
|
|
160
|
+
теги печатает хост, и выбрать между `type="module"` и обычным `defer` он может только по этому
|
|
161
|
+
признаку.
|
|
162
|
+
|
|
128
163
|
## Сетевой транспорт: то же самое по HTTP
|
|
129
164
|
|
|
130
165
|
Приложение поднимается отдельным сервисом **без единой строки своего серверного кода** —
|
package/bin/den.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var _chunk3X4WVHUUcjs = require('../chunk-3X4WVHUU.cjs');
|
|
5
5
|
require('../chunk-KQAB6C6Q.cjs');
|
|
6
6
|
require('../chunk-A6ZPAM6Z.cjs');
|
|
7
7
|
|
|
@@ -70,11 +70,11 @@ function run(argv) {
|
|
|
70
70
|
}
|
|
71
71
|
const target = { base: options["base"], root: (_a = options["root"]) != null ? _a : process.cwd() };
|
|
72
72
|
if (command === "build") {
|
|
73
|
-
yield
|
|
73
|
+
yield _chunk3X4WVHUUcjs.buildApp.call(void 0, target);
|
|
74
74
|
return;
|
|
75
75
|
}
|
|
76
76
|
if (command === "dev") {
|
|
77
|
-
yield
|
|
77
|
+
yield _chunk3X4WVHUUcjs.devApp.call(void 0, target);
|
|
78
78
|
return;
|
|
79
79
|
}
|
|
80
80
|
fail(`\u043D\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043D\u0430\u044F \u043A\u043E\u043C\u0430\u043D\u0434\u0430 \xAB${command}\xBB`);
|
package/bin/den.js
CHANGED
package/builder/index.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var _chunk3X4WVHUUcjs = require('../chunk-3X4WVHUU.cjs');
|
|
6
6
|
require('../chunk-KQAB6C6Q.cjs');
|
|
7
7
|
require('../chunk-A6ZPAM6Z.cjs');
|
|
8
8
|
require('../chunk-T5QVCXVB.cjs');
|
|
@@ -10,4 +10,4 @@ require('../chunk-T5QVCXVB.cjs');
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
exports.buildApp =
|
|
13
|
+
exports.buildApp = _chunk3X4WVHUUcjs.buildApp; exports.defineAppConfig = _chunk3X4WVHUUcjs.defineAppConfig; exports.devApp = _chunk3X4WVHUUcjs.devApp;
|
package/builder/index.d.cts
CHANGED
|
@@ -80,13 +80,18 @@ interface AppServerConfig {
|
|
|
80
80
|
interface AppConfig {
|
|
81
81
|
/** Модуль дескриптора; по умолчанию `src/index.ts`. */
|
|
82
82
|
entry?: string;
|
|
83
|
-
/**
|
|
84
|
-
|
|
83
|
+
/**
|
|
84
|
+
* Пресет фреймворка — из пакета адаптера.
|
|
85
|
+
*
|
|
86
|
+
* Не объявлен — приложение своего фрагмента не рисует (дескриптор без `view`), и клиентского
|
|
87
|
+
* выхода у него не бывает: собирать нечем и оживлять нечего.
|
|
88
|
+
*/
|
|
89
|
+
preset?: AppBuildPreset;
|
|
85
90
|
server?: AppServerConfig;
|
|
86
91
|
/**
|
|
87
92
|
* Последнее слово за приложением: правит собранный конфиг сборщика перед запуском.
|
|
88
93
|
*
|
|
89
|
-
* Щель на случай, когда
|
|
94
|
+
* Щель на случай, когда умолчаний сборки не хватило. Зовётся отдельно для каждого выхода, поэтому
|
|
90
95
|
* правка адресуется тому, кому предназначена.
|
|
91
96
|
*/
|
|
92
97
|
vite?: (config: Record<string, unknown>, target: 'server' | 'client') => Record<string, unknown>;
|
package/builder/index.d.ts
CHANGED
|
@@ -80,13 +80,18 @@ interface AppServerConfig {
|
|
|
80
80
|
interface AppConfig {
|
|
81
81
|
/** Модуль дескриптора; по умолчанию `src/index.ts`. */
|
|
82
82
|
entry?: string;
|
|
83
|
-
/**
|
|
84
|
-
|
|
83
|
+
/**
|
|
84
|
+
* Пресет фреймворка — из пакета адаптера.
|
|
85
|
+
*
|
|
86
|
+
* Не объявлен — приложение своего фрагмента не рисует (дескриптор без `view`), и клиентского
|
|
87
|
+
* выхода у него не бывает: собирать нечем и оживлять нечего.
|
|
88
|
+
*/
|
|
89
|
+
preset?: AppBuildPreset;
|
|
85
90
|
server?: AppServerConfig;
|
|
86
91
|
/**
|
|
87
92
|
* Последнее слово за приложением: правит собранный конфиг сборщика перед запуском.
|
|
88
93
|
*
|
|
89
|
-
* Щель на случай, когда
|
|
94
|
+
* Щель на случай, когда умолчаний сборки не хватило. Зовётся отдельно для каждого выхода, поэтому
|
|
90
95
|
* правка адресуется тому, кому предназначена.
|
|
91
96
|
*/
|
|
92
97
|
vite?: (config: Record<string, unknown>, target: 'server' | 'client') => Record<string, unknown>;
|
package/builder/index.js
CHANGED
|
@@ -95,7 +95,9 @@ import config from ${JSON.stringify(configPath)}
|
|
|
95
95
|
const server = config.server ?? {}
|
|
96
96
|
|
|
97
97
|
async function setup() {
|
|
98
|
-
|
|
98
|
+
if (app.viewLayer) {
|
|
99
|
+
viewAdapterOf(app.viewLayer).installResolver()
|
|
100
|
+
}
|
|
99
101
|
server.container?.(getAppContainer())
|
|
100
102
|
await server.setup?.()
|
|
101
103
|
}
|
|
@@ -134,7 +136,14 @@ ${assets} configure: config.server?.configure,
|
|
|
134
136
|
function denAppModules(options) {
|
|
135
137
|
const { assets, base, config, configPath, entry, mode } = options;
|
|
136
138
|
const sources = {
|
|
137
|
-
|
|
139
|
+
// Клиентский вход спрашивают только у клиентского выхода, а его без пресета не собирают.
|
|
140
|
+
// Отказ здесь означает, что выход всё-таки запустили, — это ошибка команд, а не приложения
|
|
141
|
+
[VIRTUAL_CLIENT]: () => {
|
|
142
|
+
if (!config.preset) {
|
|
143
|
+
throw new Error("den: \u043A\u043B\u0438\u0435\u043D\u0442\u0441\u043A\u0438\u0439 \u0432\u0445\u043E\u0434 \u0437\u0430\u043F\u0440\u043E\u0448\u0435\u043D, \u043D\u043E \u043F\u0440\u0435\u0441\u0435\u0442 \u043D\u0435 \u043E\u0431\u044A\u044F\u0432\u043B\u0435\u043D \u2014 \u043E\u0436\u0438\u0432\u043B\u044F\u0442\u044C \u043D\u0435\u0447\u0435\u043C");
|
|
144
|
+
}
|
|
145
|
+
return generateClientEntry(entry, config.preset.clientEntry);
|
|
146
|
+
},
|
|
138
147
|
[VIRTUAL_SERVER_APP]: () => generateServerApp(entry, configPath, assets),
|
|
139
148
|
[VIRTUAL_SERVER_PROCESS]: () => generateServerProcess(configPath, base, mode)
|
|
140
149
|
};
|
|
@@ -175,8 +184,8 @@ function loadAppConfig(root) {
|
|
|
175
184
|
try {
|
|
176
185
|
const loaded = yield server.ssrLoadModule(configPath);
|
|
177
186
|
const config = loaded.default;
|
|
178
|
-
if (!
|
|
179
|
-
throw new Error(`den: ${CONFIG_FILE} \u043D\u0435 \u043E\
|
|
187
|
+
if (!config) {
|
|
188
|
+
throw new Error(`den: ${CONFIG_FILE} \u043D\u0435 \u043E\u0442\u0434\u0430\u0451\u0442 \u043A\u043E\u043D\u0444\u0438\u0433 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u2014 \u0441\u043E\u0431\u0438\u0440\u0430\u0442\u044C \u043D\u0435\u0447\u0435\u043C`);
|
|
180
189
|
}
|
|
181
190
|
return { config, configPath };
|
|
182
191
|
} finally {
|
|
@@ -194,7 +203,7 @@ function dependenciesOf(root) {
|
|
|
194
203
|
return [...Object.keys((_a = manifest.dependencies) != null ? _a : {}), ...Object.keys((_b = manifest.devDependencies) != null ? _b : {})];
|
|
195
204
|
}
|
|
196
205
|
function viteConfigFor(options) {
|
|
197
|
-
var _a, _b, _c;
|
|
206
|
+
var _a, _b, _c, _d, _e;
|
|
198
207
|
const { assets, base, config, configPath, entryFileNames, input, mode, outDir, root, target } = options;
|
|
199
208
|
const entry = (_a = config.entry) != null ? _a : "src/index.ts";
|
|
200
209
|
const composed = {
|
|
@@ -219,17 +228,17 @@ function viteConfigFor(options) {
|
|
|
219
228
|
// программный вызов он иначе не доедет.
|
|
220
229
|
mode,
|
|
221
230
|
plugins: [
|
|
222
|
-
...config.preset.plugins,
|
|
231
|
+
...(_c = (_b = config.preset) == null ? void 0 : _b.plugins) != null ? _c : [],
|
|
223
232
|
denAppModules({ assets, base, config, configPath, entry: _path2.default.join(root, entry), mode })
|
|
224
233
|
],
|
|
225
234
|
root,
|
|
226
|
-
ssr: { noExternal: (
|
|
235
|
+
ssr: { noExternal: (_e = (_d = config.server) == null ? void 0 : _d.noExternal) != null ? _e : [] }
|
|
227
236
|
};
|
|
228
237
|
return config.vite ? config.vite(composed, target) : composed;
|
|
229
238
|
}
|
|
230
239
|
function buildApp(options) {
|
|
231
240
|
return _chunkT5QVCXVBcjs.__async.call(void 0, this, null, function* () {
|
|
232
|
-
var _a, _b, _c
|
|
241
|
+
var _a, _b, _c;
|
|
233
242
|
const { mode = "production" } = options;
|
|
234
243
|
process.env["NODE_ENV"] = mode;
|
|
235
244
|
const root = _path2.default.resolve(options.root);
|
|
@@ -237,17 +246,25 @@ function buildApp(options) {
|
|
|
237
246
|
const { config, configPath } = yield loadAppConfig(root);
|
|
238
247
|
const port = resolvePort((_a = config.server) == null ? void 0 : _a.port);
|
|
239
248
|
const base = (_b = options.base) != null ? _b : "";
|
|
240
|
-
const
|
|
249
|
+
const { preset } = config;
|
|
250
|
+
const refusal = (_c = preset == null ? void 0 : preset.validate) == null ? void 0 : _c.call(preset, dependenciesOf(root));
|
|
241
251
|
if (refusal !== void 0 && refusal !== null) {
|
|
242
252
|
throw new Error(`den: ${refusal}`);
|
|
243
253
|
}
|
|
244
254
|
const { build } = yield Promise.resolve().then(() => _interopRequireWildcard(require("vite")));
|
|
245
255
|
const shared = { base, config, configPath, mode, root };
|
|
246
256
|
const empty = { css: [], js: [] };
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
257
|
+
let assets = empty;
|
|
258
|
+
if (preset) {
|
|
259
|
+
_chunkA6ZPAM6Zcjs.logger.info(`\u0441\u0431\u043E\u0440\u043A\u0430 \u043A\u043B\u0438\u0435\u043D\u0442\u0441\u043A\u043E\u0433\u043E \u0432\u044B\u0445\u043E\u0434\u0430 (${preset.view})`);
|
|
260
|
+
yield build(
|
|
261
|
+
viteConfigFor(_chunkT5QVCXVBcjs.__spreadProps.call(void 0, _chunkT5QVCXVBcjs.__spreadValues.call(void 0, {}, shared), { assets: empty, input: VIRTUAL_CLIENT, outDir: OUT_CLIENT, target: "client" }))
|
|
262
|
+
);
|
|
263
|
+
assets = collectAssets(_path2.default.join(root, OUT_CLIENT), base);
|
|
264
|
+
_chunkA6ZPAM6Zcjs.logger.info(`\u0430\u0440\u0442\u0435\u0444\u0430\u043A\u0442\u044B: ${String(assets.js.length)} js, ${String(assets.css.length)} css`);
|
|
265
|
+
} else {
|
|
266
|
+
_chunkA6ZPAM6Zcjs.logger.info("\u043A\u043B\u0438\u0435\u043D\u0442\u0441\u043A\u043E\u0433\u043E \u0432\u044B\u0445\u043E\u0434\u0430 \u043D\u0435\u0442: \u043F\u0440\u0435\u0441\u0435\u0442 \u043D\u0435 \u043E\u0431\u044A\u044F\u0432\u043B\u0435\u043D, \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \u0441\u0432\u043E\u0435\u0433\u043E \u0444\u0440\u0430\u0433\u043C\u0435\u043D\u0442\u0430 \u043D\u0435 \u0440\u0438\u0441\u0443\u0435\u0442");
|
|
267
|
+
}
|
|
251
268
|
_chunkA6ZPAM6Zcjs.logger.info("\u0441\u0431\u043E\u0440\u043A\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u043D\u043E\u0433\u043E \u0434\u0435\u0441\u043A\u0440\u0438\u043F\u0442\u043E\u0440\u0430");
|
|
252
269
|
yield build(
|
|
253
270
|
viteConfigFor(_chunkT5QVCXVBcjs.__spreadProps.call(void 0, _chunkT5QVCXVBcjs.__spreadValues.call(void 0, {}, shared), {
|
|
@@ -35,29 +35,33 @@ function getAppContainer() {
|
|
|
35
35
|
import { log } from "@foxford/logger";
|
|
36
36
|
var EMPTY_ROUTE = { params: {}, pathname: "", search: "" };
|
|
37
37
|
var REDIRECT_FOUND = 302;
|
|
38
|
+
function registerIslandParts(container, descriptor, islandLog) {
|
|
39
|
+
var _a, _b, _c;
|
|
40
|
+
(_a = descriptor.viewLayer) == null ? void 0 : _a.register(container);
|
|
41
|
+
const viewModels = (_b = descriptor.viewModels) != null ? _b : [];
|
|
42
|
+
const slots = Object.entries((_c = descriptor.slots) != null ? _c : {});
|
|
43
|
+
islandLog.info(
|
|
44
|
+
`\u043E\u0441\u0442\u0440\u043E\u0432: \u043A\u043E\u043D\u0442\u0435\u0439\u043D\u0435\u0440 \u0441\u043E\u0437\u0434\u0430\u043D (units=${descriptor.units.length}, vms=${viewModels.length}, slots=${slots.length})`
|
|
45
|
+
);
|
|
46
|
+
for (const unit of descriptor.units) {
|
|
47
|
+
unit.register(container);
|
|
48
|
+
}
|
|
49
|
+
for (const vm of viewModels) {
|
|
50
|
+
vm.register(container);
|
|
51
|
+
}
|
|
52
|
+
for (const [name, slot] of slots) {
|
|
53
|
+
slot.register(container, name);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
38
56
|
function createIslandContainer(descriptor, options = {}) {
|
|
39
|
-
var _a, _b, _c
|
|
57
|
+
var _a, _b, _c;
|
|
40
58
|
const { parent = getAppContainer() } = options;
|
|
41
59
|
const appLog = (_b = log.getLogger((_a = descriptor.name) != null ? _a : "app")) != null ? _b : logger;
|
|
42
60
|
const islandLog = (_c = appLog.getLogger("client")) != null ? _c : appLog;
|
|
43
61
|
try {
|
|
44
62
|
const container = parent.createChild();
|
|
45
63
|
container.bind(LoggerToken).toValue(islandLog);
|
|
46
|
-
|
|
47
|
-
const viewModels = (_d = descriptor.viewModels) != null ? _d : [];
|
|
48
|
-
const slots = Object.entries((_e = descriptor.slots) != null ? _e : {});
|
|
49
|
-
islandLog.info(
|
|
50
|
-
`\u043E\u0441\u0442\u0440\u043E\u0432: \u043A\u043E\u043D\u0442\u0435\u0439\u043D\u0435\u0440 \u0441\u043E\u0437\u0434\u0430\u043D (units=${descriptor.units.length}, vms=${viewModels.length}, slots=${slots.length})`
|
|
51
|
-
);
|
|
52
|
-
for (const unit of descriptor.units) {
|
|
53
|
-
unit.register(container);
|
|
54
|
-
}
|
|
55
|
-
for (const vm of viewModels) {
|
|
56
|
-
vm.register(container);
|
|
57
|
-
}
|
|
58
|
-
for (const [name, slot] of slots) {
|
|
59
|
-
slot.register(container, name);
|
|
60
|
-
}
|
|
64
|
+
registerIslandParts(container, descriptor, islandLog);
|
|
61
65
|
return container;
|
|
62
66
|
} catch (error) {
|
|
63
67
|
islandLog.error("\u043E\u0441\u0442\u0440\u043E\u0432: \u0441\u0431\u043E\u0440\u043A\u0430 \u043A\u043E\u043D\u0442\u0435\u0439\u043D\u0435\u0440\u0430 \u0443\u043F\u0430\u043B\u0430", error);
|
|
@@ -111,6 +115,12 @@ function collectDocumentContribution(container, descriptor) {
|
|
|
111
115
|
if (part.head) {
|
|
112
116
|
contribution.head = __spreadValues(__spreadValues({}, contribution.head), part.head);
|
|
113
117
|
}
|
|
118
|
+
if (part.data) {
|
|
119
|
+
contribution.data = __spreadValues(__spreadValues({}, contribution.data), part.data);
|
|
120
|
+
}
|
|
121
|
+
if (part.assets && contribution.assets === void 0) {
|
|
122
|
+
contribution.assets = part.assets;
|
|
123
|
+
}
|
|
114
124
|
const declared = part.status !== void 0 || part.redirect !== void 0;
|
|
115
125
|
if (declared && contribution.status === void 0) {
|
|
116
126
|
contribution.status = (_b = part.status) != null ? _b : REDIRECT_FOUND;
|
|
@@ -149,7 +159,7 @@ function setupOnce(descriptor) {
|
|
|
149
159
|
}
|
|
150
160
|
function renderApp(descriptor, request) {
|
|
151
161
|
return __async(this, null, function* () {
|
|
152
|
-
var _a, _b;
|
|
162
|
+
var _a, _b, _c;
|
|
153
163
|
yield setupOnce(descriptor);
|
|
154
164
|
const route = {
|
|
155
165
|
params: (_a = request.params) != null ? _a : {},
|
|
@@ -165,16 +175,21 @@ function renderApp(descriptor, request) {
|
|
|
165
175
|
container.bind(RequestContextToken).toValue(request.context);
|
|
166
176
|
}
|
|
167
177
|
yield activateIslandViewModels(container, descriptor, route);
|
|
168
|
-
const
|
|
178
|
+
const contribution = collectDocumentContribution(container, descriptor);
|
|
179
|
+
const { data, head, redirect, status = STATUS_OK } = contribution;
|
|
169
180
|
if (status !== STATUS_OK) {
|
|
170
|
-
return { head, html: "", redirect, state: {}, status };
|
|
181
|
+
return { data, head, html: "", redirect, state: {}, status };
|
|
171
182
|
}
|
|
183
|
+
const assets = (_c = contribution.assets) != null ? _c : descriptor.assets;
|
|
172
184
|
const state = collectIslandState(container, descriptor);
|
|
185
|
+
if (descriptor.view === void 0 || descriptor.viewLayer === void 0) {
|
|
186
|
+
return { assets, data, head, html: "", state, status };
|
|
187
|
+
}
|
|
173
188
|
const rendered = resolveViewAdapter(container).renderIsland(descriptor, {
|
|
174
189
|
container,
|
|
175
190
|
slots: request.slots
|
|
176
191
|
});
|
|
177
|
-
return { assets
|
|
192
|
+
return { assets, data, head, headHtml: rendered.head, html: rendered.html, state, status };
|
|
178
193
|
} finally {
|
|
179
194
|
yield container.dispose();
|
|
180
195
|
}
|
|
@@ -35,29 +35,33 @@ function getAppContainer() {
|
|
|
35
35
|
var _logger = require('@foxford/logger');
|
|
36
36
|
var EMPTY_ROUTE = { params: {}, pathname: "", search: "" };
|
|
37
37
|
var REDIRECT_FOUND = 302;
|
|
38
|
+
function registerIslandParts(container, descriptor, islandLog) {
|
|
39
|
+
var _a, _b, _c;
|
|
40
|
+
(_a = descriptor.viewLayer) == null ? void 0 : _a.register(container);
|
|
41
|
+
const viewModels = (_b = descriptor.viewModels) != null ? _b : [];
|
|
42
|
+
const slots = Object.entries((_c = descriptor.slots) != null ? _c : {});
|
|
43
|
+
islandLog.info(
|
|
44
|
+
`\u043E\u0441\u0442\u0440\u043E\u0432: \u043A\u043E\u043D\u0442\u0435\u0439\u043D\u0435\u0440 \u0441\u043E\u0437\u0434\u0430\u043D (units=${descriptor.units.length}, vms=${viewModels.length}, slots=${slots.length})`
|
|
45
|
+
);
|
|
46
|
+
for (const unit of descriptor.units) {
|
|
47
|
+
unit.register(container);
|
|
48
|
+
}
|
|
49
|
+
for (const vm of viewModels) {
|
|
50
|
+
vm.register(container);
|
|
51
|
+
}
|
|
52
|
+
for (const [name, slot] of slots) {
|
|
53
|
+
slot.register(container, name);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
38
56
|
function createIslandContainer(descriptor, options = {}) {
|
|
39
|
-
var _a, _b, _c
|
|
57
|
+
var _a, _b, _c;
|
|
40
58
|
const { parent = getAppContainer() } = options;
|
|
41
59
|
const appLog = (_b = _logger.log.getLogger((_a = descriptor.name) != null ? _a : "app")) != null ? _b : _chunkA6ZPAM6Zcjs.logger;
|
|
42
60
|
const islandLog = (_c = appLog.getLogger("client")) != null ? _c : appLog;
|
|
43
61
|
try {
|
|
44
62
|
const container = parent.createChild();
|
|
45
63
|
container.bind(_chunkA6ZPAM6Zcjs.LoggerToken).toValue(islandLog);
|
|
46
|
-
|
|
47
|
-
const viewModels = (_d = descriptor.viewModels) != null ? _d : [];
|
|
48
|
-
const slots = Object.entries((_e = descriptor.slots) != null ? _e : {});
|
|
49
|
-
islandLog.info(
|
|
50
|
-
`\u043E\u0441\u0442\u0440\u043E\u0432: \u043A\u043E\u043D\u0442\u0435\u0439\u043D\u0435\u0440 \u0441\u043E\u0437\u0434\u0430\u043D (units=${descriptor.units.length}, vms=${viewModels.length}, slots=${slots.length})`
|
|
51
|
-
);
|
|
52
|
-
for (const unit of descriptor.units) {
|
|
53
|
-
unit.register(container);
|
|
54
|
-
}
|
|
55
|
-
for (const vm of viewModels) {
|
|
56
|
-
vm.register(container);
|
|
57
|
-
}
|
|
58
|
-
for (const [name, slot] of slots) {
|
|
59
|
-
slot.register(container, name);
|
|
60
|
-
}
|
|
64
|
+
registerIslandParts(container, descriptor, islandLog);
|
|
61
65
|
return container;
|
|
62
66
|
} catch (error) {
|
|
63
67
|
islandLog.error("\u043E\u0441\u0442\u0440\u043E\u0432: \u0441\u0431\u043E\u0440\u043A\u0430 \u043A\u043E\u043D\u0442\u0435\u0439\u043D\u0435\u0440\u0430 \u0443\u043F\u0430\u043B\u0430", error);
|
|
@@ -111,6 +115,12 @@ function collectDocumentContribution(container, descriptor) {
|
|
|
111
115
|
if (part.head) {
|
|
112
116
|
contribution.head = _chunkT5QVCXVBcjs.__spreadValues.call(void 0, _chunkT5QVCXVBcjs.__spreadValues.call(void 0, {}, contribution.head), part.head);
|
|
113
117
|
}
|
|
118
|
+
if (part.data) {
|
|
119
|
+
contribution.data = _chunkT5QVCXVBcjs.__spreadValues.call(void 0, _chunkT5QVCXVBcjs.__spreadValues.call(void 0, {}, contribution.data), part.data);
|
|
120
|
+
}
|
|
121
|
+
if (part.assets && contribution.assets === void 0) {
|
|
122
|
+
contribution.assets = part.assets;
|
|
123
|
+
}
|
|
114
124
|
const declared = part.status !== void 0 || part.redirect !== void 0;
|
|
115
125
|
if (declared && contribution.status === void 0) {
|
|
116
126
|
contribution.status = (_b = part.status) != null ? _b : REDIRECT_FOUND;
|
|
@@ -149,7 +159,7 @@ function setupOnce(descriptor) {
|
|
|
149
159
|
}
|
|
150
160
|
function renderApp(descriptor, request) {
|
|
151
161
|
return _chunkT5QVCXVBcjs.__async.call(void 0, this, null, function* () {
|
|
152
|
-
var _a, _b;
|
|
162
|
+
var _a, _b, _c;
|
|
153
163
|
yield setupOnce(descriptor);
|
|
154
164
|
const route = {
|
|
155
165
|
params: (_a = request.params) != null ? _a : {},
|
|
@@ -165,16 +175,21 @@ function renderApp(descriptor, request) {
|
|
|
165
175
|
container.bind(_chunk6QV4L6R2cjs.RequestContextToken).toValue(request.context);
|
|
166
176
|
}
|
|
167
177
|
yield activateIslandViewModels(container, descriptor, route);
|
|
168
|
-
const
|
|
178
|
+
const contribution = collectDocumentContribution(container, descriptor);
|
|
179
|
+
const { data, head, redirect, status = STATUS_OK } = contribution;
|
|
169
180
|
if (status !== STATUS_OK) {
|
|
170
|
-
return { head, html: "", redirect, state: {}, status };
|
|
181
|
+
return { data, head, html: "", redirect, state: {}, status };
|
|
171
182
|
}
|
|
183
|
+
const assets = (_c = contribution.assets) != null ? _c : descriptor.assets;
|
|
172
184
|
const state = collectIslandState(container, descriptor);
|
|
185
|
+
if (descriptor.view === void 0 || descriptor.viewLayer === void 0) {
|
|
186
|
+
return { assets, data, head, html: "", state, status };
|
|
187
|
+
}
|
|
173
188
|
const rendered = _chunkXOJ2VWX4cjs.resolveViewAdapter.call(void 0, container).renderIsland(descriptor, {
|
|
174
189
|
container,
|
|
175
190
|
slots: request.slots
|
|
176
191
|
});
|
|
177
|
-
return { assets
|
|
192
|
+
return { assets, data, head, headHtml: rendered.head, html: rendered.html, state, status };
|
|
178
193
|
} finally {
|
|
179
194
|
yield container.dispose();
|
|
180
195
|
}
|
|
@@ -95,7 +95,9 @@ import config from ${JSON.stringify(configPath)}
|
|
|
95
95
|
const server = config.server ?? {}
|
|
96
96
|
|
|
97
97
|
async function setup() {
|
|
98
|
-
|
|
98
|
+
if (app.viewLayer) {
|
|
99
|
+
viewAdapterOf(app.viewLayer).installResolver()
|
|
100
|
+
}
|
|
99
101
|
server.container?.(getAppContainer())
|
|
100
102
|
await server.setup?.()
|
|
101
103
|
}
|
|
@@ -134,7 +136,14 @@ ${assets} configure: config.server?.configure,
|
|
|
134
136
|
function denAppModules(options) {
|
|
135
137
|
const { assets, base, config, configPath, entry, mode } = options;
|
|
136
138
|
const sources = {
|
|
137
|
-
|
|
139
|
+
// Клиентский вход спрашивают только у клиентского выхода, а его без пресета не собирают.
|
|
140
|
+
// Отказ здесь означает, что выход всё-таки запустили, — это ошибка команд, а не приложения
|
|
141
|
+
[VIRTUAL_CLIENT]: () => {
|
|
142
|
+
if (!config.preset) {
|
|
143
|
+
throw new Error("den: \u043A\u043B\u0438\u0435\u043D\u0442\u0441\u043A\u0438\u0439 \u0432\u0445\u043E\u0434 \u0437\u0430\u043F\u0440\u043E\u0448\u0435\u043D, \u043D\u043E \u043F\u0440\u0435\u0441\u0435\u0442 \u043D\u0435 \u043E\u0431\u044A\u044F\u0432\u043B\u0435\u043D \u2014 \u043E\u0436\u0438\u0432\u043B\u044F\u0442\u044C \u043D\u0435\u0447\u0435\u043C");
|
|
144
|
+
}
|
|
145
|
+
return generateClientEntry(entry, config.preset.clientEntry);
|
|
146
|
+
},
|
|
138
147
|
[VIRTUAL_SERVER_APP]: () => generateServerApp(entry, configPath, assets),
|
|
139
148
|
[VIRTUAL_SERVER_PROCESS]: () => generateServerProcess(configPath, base, mode)
|
|
140
149
|
};
|
|
@@ -175,8 +184,8 @@ function loadAppConfig(root) {
|
|
|
175
184
|
try {
|
|
176
185
|
const loaded = yield server.ssrLoadModule(configPath);
|
|
177
186
|
const config = loaded.default;
|
|
178
|
-
if (!
|
|
179
|
-
throw new Error(`den: ${CONFIG_FILE} \u043D\u0435 \u043E\
|
|
187
|
+
if (!config) {
|
|
188
|
+
throw new Error(`den: ${CONFIG_FILE} \u043D\u0435 \u043E\u0442\u0434\u0430\u0451\u0442 \u043A\u043E\u043D\u0444\u0438\u0433 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u2014 \u0441\u043E\u0431\u0438\u0440\u0430\u0442\u044C \u043D\u0435\u0447\u0435\u043C`);
|
|
180
189
|
}
|
|
181
190
|
return { config, configPath };
|
|
182
191
|
} finally {
|
|
@@ -194,7 +203,7 @@ function dependenciesOf(root) {
|
|
|
194
203
|
return [...Object.keys((_a = manifest.dependencies) != null ? _a : {}), ...Object.keys((_b = manifest.devDependencies) != null ? _b : {})];
|
|
195
204
|
}
|
|
196
205
|
function viteConfigFor(options) {
|
|
197
|
-
var _a, _b, _c;
|
|
206
|
+
var _a, _b, _c, _d, _e;
|
|
198
207
|
const { assets, base, config, configPath, entryFileNames, input, mode, outDir, root, target } = options;
|
|
199
208
|
const entry = (_a = config.entry) != null ? _a : "src/index.ts";
|
|
200
209
|
const composed = {
|
|
@@ -219,17 +228,17 @@ function viteConfigFor(options) {
|
|
|
219
228
|
// программный вызов он иначе не доедет.
|
|
220
229
|
mode,
|
|
221
230
|
plugins: [
|
|
222
|
-
...config.preset.plugins,
|
|
231
|
+
...(_c = (_b = config.preset) == null ? void 0 : _b.plugins) != null ? _c : [],
|
|
223
232
|
denAppModules({ assets, base, config, configPath, entry: path2.join(root, entry), mode })
|
|
224
233
|
],
|
|
225
234
|
root,
|
|
226
|
-
ssr: { noExternal: (
|
|
235
|
+
ssr: { noExternal: (_e = (_d = config.server) == null ? void 0 : _d.noExternal) != null ? _e : [] }
|
|
227
236
|
};
|
|
228
237
|
return config.vite ? config.vite(composed, target) : composed;
|
|
229
238
|
}
|
|
230
239
|
function buildApp(options) {
|
|
231
240
|
return __async(this, null, function* () {
|
|
232
|
-
var _a, _b, _c
|
|
241
|
+
var _a, _b, _c;
|
|
233
242
|
const { mode = "production" } = options;
|
|
234
243
|
process.env["NODE_ENV"] = mode;
|
|
235
244
|
const root = path2.resolve(options.root);
|
|
@@ -237,17 +246,25 @@ function buildApp(options) {
|
|
|
237
246
|
const { config, configPath } = yield loadAppConfig(root);
|
|
238
247
|
const port = resolvePort((_a = config.server) == null ? void 0 : _a.port);
|
|
239
248
|
const base = (_b = options.base) != null ? _b : "";
|
|
240
|
-
const
|
|
249
|
+
const { preset } = config;
|
|
250
|
+
const refusal = (_c = preset == null ? void 0 : preset.validate) == null ? void 0 : _c.call(preset, dependenciesOf(root));
|
|
241
251
|
if (refusal !== void 0 && refusal !== null) {
|
|
242
252
|
throw new Error(`den: ${refusal}`);
|
|
243
253
|
}
|
|
244
254
|
const { build } = yield import("vite");
|
|
245
255
|
const shared = { base, config, configPath, mode, root };
|
|
246
256
|
const empty = { css: [], js: [] };
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
257
|
+
let assets = empty;
|
|
258
|
+
if (preset) {
|
|
259
|
+
logger.info(`\u0441\u0431\u043E\u0440\u043A\u0430 \u043A\u043B\u0438\u0435\u043D\u0442\u0441\u043A\u043E\u0433\u043E \u0432\u044B\u0445\u043E\u0434\u0430 (${preset.view})`);
|
|
260
|
+
yield build(
|
|
261
|
+
viteConfigFor(__spreadProps(__spreadValues({}, shared), { assets: empty, input: VIRTUAL_CLIENT, outDir: OUT_CLIENT, target: "client" }))
|
|
262
|
+
);
|
|
263
|
+
assets = collectAssets(path2.join(root, OUT_CLIENT), base);
|
|
264
|
+
logger.info(`\u0430\u0440\u0442\u0435\u0444\u0430\u043A\u0442\u044B: ${String(assets.js.length)} js, ${String(assets.css.length)} css`);
|
|
265
|
+
} else {
|
|
266
|
+
logger.info("\u043A\u043B\u0438\u0435\u043D\u0442\u0441\u043A\u043E\u0433\u043E \u0432\u044B\u0445\u043E\u0434\u0430 \u043D\u0435\u0442: \u043F\u0440\u0435\u0441\u0435\u0442 \u043D\u0435 \u043E\u0431\u044A\u044F\u0432\u043B\u0435\u043D, \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \u0441\u0432\u043E\u0435\u0433\u043E \u0444\u0440\u0430\u0433\u043C\u0435\u043D\u0442\u0430 \u043D\u0435 \u0440\u0438\u0441\u0443\u0435\u0442");
|
|
267
|
+
}
|
|
251
268
|
logger.info("\u0441\u0431\u043E\u0440\u043A\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u043D\u043E\u0433\u043E \u0434\u0435\u0441\u043A\u0440\u0438\u043F\u0442\u043E\u0440\u0430");
|
|
252
269
|
yield build(
|
|
253
270
|
viteConfigFor(__spreadProps(__spreadValues({}, shared), {
|
|
@@ -14,6 +14,11 @@ import { Token } from '@foxford/ioc';
|
|
|
14
14
|
* шире: у каждого своя часть про оркестрацию — `load`, `routes`, `provides`/`requires`,
|
|
15
15
|
* вклад в документ. Сводить их в один тип нечем, оркестраторы у хостов разные. Общее
|
|
16
16
|
* ровно это, и структурная типизация делает остальное: дескриптор хоста подходит сюда как есть.
|
|
17
|
+
*
|
|
18
|
+
* `view` и `viewLayer` объявляются ПАРОЙ либо не объявляются вовсе. Приложение без них —
|
|
19
|
+
* законный случай: оно сообщает документу данные (`describeDocument`), а рисует его кусок
|
|
20
|
+
* кто-то другой, например клиент монолита. Жизненный цикл у такого приложения тот же —
|
|
21
|
+
* контейнер, единицы, активация VM, — поэтому второго вида дескриптора нет.
|
|
17
22
|
*/
|
|
18
23
|
interface IslandDescriptor {
|
|
19
24
|
/**
|
|
@@ -25,16 +30,16 @@ interface IslandDescriptor {
|
|
|
25
30
|
* второго оно обязательное: без него у мест приложения не было бы адреса.
|
|
26
31
|
*/
|
|
27
32
|
name: string;
|
|
28
|
-
/** Непрозрачная ссылка на view острова (компонент view-фреймворка)
|
|
29
|
-
view
|
|
33
|
+
/** Непрозрачная ссылка на view острова (компонент view-фреймворка); нет — приложение не рисует. */
|
|
34
|
+
view?: unknown;
|
|
30
35
|
/**
|
|
31
36
|
* View-слой — чем остров рисовать: `defineLayer(ViewLayerToken, { adapter: reactAdapter() })`.
|
|
32
37
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
38
|
+
* Дефолта нет ни у ядра, ни у хоста: фреймворк за приложение не выбирают. Слой
|
|
39
|
+
* регистрируется в контейнере острова, поэтому слоты внутри по умолчанию рисуются им же;
|
|
40
|
+
* слот перекрывает выбор своим `viewLayer`.
|
|
36
41
|
*/
|
|
37
|
-
viewLayer
|
|
42
|
+
viewLayer?: LayerDefinition;
|
|
38
43
|
/**
|
|
39
44
|
* Data/Business единицы (repository/service). Регистрируются в контейнере острова.
|
|
40
45
|
* Не должны импортировать VM.
|
|
@@ -89,10 +94,15 @@ interface IslandDescriptor {
|
|
|
89
94
|
*
|
|
90
95
|
* Ленивые чанки сюда не попадают — их браузер дотянет сам по мере надобности, а хосту
|
|
91
96
|
* нужно ровно то, без чего страница не оживёт.
|
|
97
|
+
*
|
|
98
|
+
* Вид скриптов объявлен здесь же, потому что знает его СБОРКА: теги печатает хост, но выбрать
|
|
99
|
+
* между `type="module"` и классическим `defer` он может, только зная, чем приложение собрано.
|
|
92
100
|
*/
|
|
93
101
|
interface AppAssets {
|
|
94
102
|
css: string[];
|
|
95
103
|
js: string[];
|
|
104
|
+
/** Чем подключать `js`; не объявлен — `module`. */
|
|
105
|
+
scripts?: 'module' | 'classic';
|
|
96
106
|
}
|
|
97
107
|
|
|
98
108
|
export type { AppAssets as A, IslandDescriptor as I };
|
|
@@ -14,6 +14,11 @@ import { Token } from '@foxford/ioc';
|
|
|
14
14
|
* шире: у каждого своя часть про оркестрацию — `load`, `routes`, `provides`/`requires`,
|
|
15
15
|
* вклад в документ. Сводить их в один тип нечем, оркестраторы у хостов разные. Общее
|
|
16
16
|
* ровно это, и структурная типизация делает остальное: дескриптор хоста подходит сюда как есть.
|
|
17
|
+
*
|
|
18
|
+
* `view` и `viewLayer` объявляются ПАРОЙ либо не объявляются вовсе. Приложение без них —
|
|
19
|
+
* законный случай: оно сообщает документу данные (`describeDocument`), а рисует его кусок
|
|
20
|
+
* кто-то другой, например клиент монолита. Жизненный цикл у такого приложения тот же —
|
|
21
|
+
* контейнер, единицы, активация VM, — поэтому второго вида дескриптора нет.
|
|
17
22
|
*/
|
|
18
23
|
interface IslandDescriptor {
|
|
19
24
|
/**
|
|
@@ -25,16 +30,16 @@ interface IslandDescriptor {
|
|
|
25
30
|
* второго оно обязательное: без него у мест приложения не было бы адреса.
|
|
26
31
|
*/
|
|
27
32
|
name: string;
|
|
28
|
-
/** Непрозрачная ссылка на view острова (компонент view-фреймворка)
|
|
29
|
-
view
|
|
33
|
+
/** Непрозрачная ссылка на view острова (компонент view-фреймворка); нет — приложение не рисует. */
|
|
34
|
+
view?: unknown;
|
|
30
35
|
/**
|
|
31
36
|
* View-слой — чем остров рисовать: `defineLayer(ViewLayerToken, { adapter: reactAdapter() })`.
|
|
32
37
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
38
|
+
* Дефолта нет ни у ядра, ни у хоста: фреймворк за приложение не выбирают. Слой
|
|
39
|
+
* регистрируется в контейнере острова, поэтому слоты внутри по умолчанию рисуются им же;
|
|
40
|
+
* слот перекрывает выбор своим `viewLayer`.
|
|
36
41
|
*/
|
|
37
|
-
viewLayer
|
|
42
|
+
viewLayer?: LayerDefinition;
|
|
38
43
|
/**
|
|
39
44
|
* Data/Business единицы (repository/service). Регистрируются в контейнере острова.
|
|
40
45
|
* Не должны импортировать VM.
|
|
@@ -89,10 +94,15 @@ interface IslandDescriptor {
|
|
|
89
94
|
*
|
|
90
95
|
* Ленивые чанки сюда не попадают — их браузер дотянет сам по мере надобности, а хосту
|
|
91
96
|
* нужно ровно то, без чего страница не оживёт.
|
|
97
|
+
*
|
|
98
|
+
* Вид скриптов объявлен здесь же, потому что знает его СБОРКА: теги печатает хост, но выбрать
|
|
99
|
+
* между `type="module"` и классическим `defer` он может, только зная, чем приложение собрано.
|
|
92
100
|
*/
|
|
93
101
|
interface AppAssets {
|
|
94
102
|
css: string[];
|
|
95
103
|
js: string[];
|
|
104
|
+
/** Чем подключать `js`; не объявлен — `module`. */
|
|
105
|
+
scripts?: 'module' | 'classic';
|
|
96
106
|
}
|
|
97
107
|
|
|
98
108
|
export type { AppAssets as A, IslandDescriptor as I };
|
package/index.d.cts
CHANGED
|
@@ -4,8 +4,8 @@ import { Container, Token } from '@foxford/ioc';
|
|
|
4
4
|
import { DefinitionResolver } from './adapter.cjs';
|
|
5
5
|
export { d as defineRepository, a as defineService, b as defineViewModel } from './define-repository-CwAXed2X.cjs';
|
|
6
6
|
export { D as DefineSlotOptions, S as SlotDefinition, d as defineSlot } from './define-slot-DYNCLDJY.cjs';
|
|
7
|
-
export { V as ViewAdapter, a as ViewLayerDefinition, b as ViewLayerToken } from './view-adapter-
|
|
8
|
-
import './descriptor-
|
|
7
|
+
export { V as ViewAdapter, a as ViewLayerDefinition, b as ViewLayerToken } from './view-adapter-Cia9blgH.cjs';
|
|
8
|
+
import './descriptor-BfsBDME1.cjs';
|
|
9
9
|
import './server-render-CocWXQKC.cjs';
|
|
10
10
|
|
|
11
11
|
/**
|
package/index.d.ts
CHANGED
|
@@ -4,8 +4,8 @@ import { Container, Token } from '@foxford/ioc';
|
|
|
4
4
|
import { DefinitionResolver } from './adapter.js';
|
|
5
5
|
export { d as defineRepository, a as defineService, b as defineViewModel } from './define-repository-q_T4hqeP.js';
|
|
6
6
|
export { D as DefineSlotOptions, S as SlotDefinition, d as defineSlot } from './define-slot-Cngzae6i.js';
|
|
7
|
-
export { V as ViewAdapter, a as ViewLayerDefinition, b as ViewLayerToken } from './view-adapter-
|
|
8
|
-
import './descriptor-
|
|
7
|
+
export { V as ViewAdapter, a as ViewLayerDefinition, b as ViewLayerToken } from './view-adapter-Bzcjotsn.js';
|
|
8
|
+
import './descriptor-D8ocBnTb.js';
|
|
9
9
|
import './server-render-CocWXQKC.js';
|
|
10
10
|
|
|
11
11
|
/**
|
package/island/index.cjs
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
var
|
|
14
|
+
var _chunkXDM6J4LJcjs = require('../chunk-XDM6J4LJ.cjs');
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
|
|
@@ -122,4 +122,4 @@ function describeIsland(descriptor, denState) {
|
|
|
122
122
|
|
|
123
123
|
|
|
124
124
|
|
|
125
|
-
exports.DOCUMENT_EVENT = DOCUMENT_EVENT; exports.NAVIGATE_EVENT = NAVIGATE_EVENT; exports.ViewLayerToken = _chunkXOJ2VWX4cjs.ViewLayerToken; exports.activateIslandViewModels =
|
|
125
|
+
exports.DOCUMENT_EVENT = DOCUMENT_EVENT; exports.NAVIGATE_EVENT = NAVIGATE_EVENT; exports.ViewLayerToken = _chunkXOJ2VWX4cjs.ViewLayerToken; exports.activateIslandViewModels = _chunkXDM6J4LJcjs.activateIslandViewModels; exports.collectDocumentContribution = _chunkXDM6J4LJcjs.collectDocumentContribution; exports.collectIslandState = _chunkXDM6J4LJcjs.collectIslandState; exports.createIslandContainer = _chunkXDM6J4LJcjs.createIslandContainer; exports.describeIsland = describeIsland; exports.getAppContainer = _chunkXDM6J4LJcjs.getAppContainer; exports.getIslandsSnapshot = getIslandsSnapshot; exports.hydrateIslandState = _chunkXDM6J4LJcjs.hydrateIslandState; exports.isDocumentSource = _chunkXDM6J4LJcjs.isDocumentSource; exports.matchRoute = _chunkXDM6J4LJcjs.matchRoute; exports.navigateIsland = navigateIsland; exports.normalizeRoutes = _chunkXDM6J4LJcjs.normalizeRoutes; exports.onIslandDocument = onIslandDocument; exports.onIslandNavigate = onIslandNavigate; exports.pathPattern = _chunkXDM6J4LJcjs.pathPattern; exports.publishIslandDocument = publishIslandDocument; exports.registerIsland = registerIsland; exports.renderApp = _chunkXDM6J4LJcjs.renderApp; exports.resolveEagerUnits = _chunkXDM6J4LJcjs.resolveEagerUnits; exports.resolveViewAdapter = _chunkXOJ2VWX4cjs.resolveViewAdapter; exports.slotAddress = slotAddress; exports.subscribeIslands = subscribeIslands; exports.viewAdapterOf = _chunkXOJ2VWX4cjs.viewAdapterOf;
|
package/island/index.d.cts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { A as AppAssets, I as IslandDescriptor } from '../descriptor-BfsBDME1.cjs';
|
|
2
2
|
import { Container } from '@foxford/ioc';
|
|
3
3
|
import { R as RequestContext } from '../types-Dx5qGiwk.cjs';
|
|
4
4
|
export { A as AppRoute, R as RouteDeclaration, a as RouteMatch, m as matchRoute, n as normalizeRoutes, p as pathPattern } from '../routes-B0hDrkiF.cjs';
|
|
5
5
|
export { R as RenderTree, a as ServerRender, S as ServerRenderResult } from '../server-render-CocWXQKC.cjs';
|
|
6
|
-
export { R as RenderIslandOptions, V as ViewAdapter, a as ViewLayerDefinition, b as ViewLayerToken, r as resolveViewAdapter, v as viewAdapterOf } from '../view-adapter-
|
|
6
|
+
export { R as RenderIslandOptions, V as ViewAdapter, a as ViewLayerDefinition, b as ViewLayerToken, r as resolveViewAdapter, v as viewAdapterOf } from '../view-adapter-Cia9blgH.cjs';
|
|
7
7
|
import '../define-slot-DYNCLDJY.cjs';
|
|
8
8
|
|
|
9
9
|
/** Вклад приложения в `<head>` документа. */
|
|
@@ -33,6 +33,10 @@ interface DocumentContribution {
|
|
|
33
33
|
status?: number;
|
|
34
34
|
/** Адрес для 3xx. Объявлен без статуса — исход `302`. */
|
|
35
35
|
redirect?: string;
|
|
36
|
+
/** Данные документа, состав которых знает только шаблон хоста. */
|
|
37
|
+
data?: Record<string, unknown>;
|
|
38
|
+
/** Артефакты этого адреса; не объявлены — берутся вплавленные сборкой. */
|
|
39
|
+
assets?: AppAssets;
|
|
36
40
|
}
|
|
37
41
|
/**
|
|
38
42
|
* VM, которой есть что сказать про документ.
|
|
@@ -138,10 +142,11 @@ declare function collectIslandState(container: Container, descriptor: IslandDesc
|
|
|
138
142
|
/**
|
|
139
143
|
* Собирает вклад острова в документ по всем его VM.
|
|
140
144
|
*
|
|
141
|
-
* Правила слияния два, и они следуют из смысла полей. `head` —
|
|
142
|
-
* объявленное позже уточняет объявленное раньше. Исход (`status` вместе с `redirect`)
|
|
143
|
-
* ОДНО
|
|
144
|
-
* статус одной VM склеился бы с адресом
|
|
145
|
+
* Правила слияния два, и они следуют из смысла полей. `head` и `data` — наборы полей, поэтому
|
|
146
|
+
* объявленное позже уточняет объявленное раньше. Исход (`status` вместе с `redirect`) и
|
|
147
|
+
* артефакты — ОДНО решение каждое, а не набор: побеждает первое объявленное, и берётся оно
|
|
148
|
+
* целиком. Иначе статус одной VM склеился бы с адресом другой, а списки чанков двух VM —
|
|
149
|
+
* в набор, который не грузил ни один клиент.
|
|
145
150
|
*
|
|
146
151
|
* @param container - Контейнер острова
|
|
147
152
|
* @param descriptor - Дескриптор острова
|
|
@@ -241,6 +246,8 @@ interface RenderAppResult {
|
|
|
241
246
|
head?: DocumentHead;
|
|
242
247
|
/** Вклад в `<head>` готовой разметкой — стили, собранные во время рендера. */
|
|
243
248
|
headHtml?: string;
|
|
249
|
+
/** Данные документа, состав которых знает шаблон хоста. */
|
|
250
|
+
data?: Record<string, unknown>;
|
|
244
251
|
/** Адрес для 3xx. */
|
|
245
252
|
redirect?: string;
|
|
246
253
|
/**
|
package/island/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { A as AppAssets, I as IslandDescriptor } from '../descriptor-D8ocBnTb.js';
|
|
2
2
|
import { Container } from '@foxford/ioc';
|
|
3
3
|
import { R as RequestContext } from '../types-Dx5qGiwk.js';
|
|
4
4
|
export { A as AppRoute, R as RouteDeclaration, a as RouteMatch, m as matchRoute, n as normalizeRoutes, p as pathPattern } from '../routes-0uXJ0fux.js';
|
|
5
5
|
export { R as RenderTree, a as ServerRender, S as ServerRenderResult } from '../server-render-CocWXQKC.js';
|
|
6
|
-
export { R as RenderIslandOptions, V as ViewAdapter, a as ViewLayerDefinition, b as ViewLayerToken, r as resolveViewAdapter, v as viewAdapterOf } from '../view-adapter-
|
|
6
|
+
export { R as RenderIslandOptions, V as ViewAdapter, a as ViewLayerDefinition, b as ViewLayerToken, r as resolveViewAdapter, v as viewAdapterOf } from '../view-adapter-Bzcjotsn.js';
|
|
7
7
|
import '../define-slot-Cngzae6i.js';
|
|
8
8
|
|
|
9
9
|
/** Вклад приложения в `<head>` документа. */
|
|
@@ -33,6 +33,10 @@ interface DocumentContribution {
|
|
|
33
33
|
status?: number;
|
|
34
34
|
/** Адрес для 3xx. Объявлен без статуса — исход `302`. */
|
|
35
35
|
redirect?: string;
|
|
36
|
+
/** Данные документа, состав которых знает только шаблон хоста. */
|
|
37
|
+
data?: Record<string, unknown>;
|
|
38
|
+
/** Артефакты этого адреса; не объявлены — берутся вплавленные сборкой. */
|
|
39
|
+
assets?: AppAssets;
|
|
36
40
|
}
|
|
37
41
|
/**
|
|
38
42
|
* VM, которой есть что сказать про документ.
|
|
@@ -138,10 +142,11 @@ declare function collectIslandState(container: Container, descriptor: IslandDesc
|
|
|
138
142
|
/**
|
|
139
143
|
* Собирает вклад острова в документ по всем его VM.
|
|
140
144
|
*
|
|
141
|
-
* Правила слияния два, и они следуют из смысла полей. `head` —
|
|
142
|
-
* объявленное позже уточняет объявленное раньше. Исход (`status` вместе с `redirect`)
|
|
143
|
-
* ОДНО
|
|
144
|
-
* статус одной VM склеился бы с адресом
|
|
145
|
+
* Правила слияния два, и они следуют из смысла полей. `head` и `data` — наборы полей, поэтому
|
|
146
|
+
* объявленное позже уточняет объявленное раньше. Исход (`status` вместе с `redirect`) и
|
|
147
|
+
* артефакты — ОДНО решение каждое, а не набор: побеждает первое объявленное, и берётся оно
|
|
148
|
+
* целиком. Иначе статус одной VM склеился бы с адресом другой, а списки чанков двух VM —
|
|
149
|
+
* в набор, который не грузил ни один клиент.
|
|
145
150
|
*
|
|
146
151
|
* @param container - Контейнер острова
|
|
147
152
|
* @param descriptor - Дескриптор острова
|
|
@@ -241,6 +246,8 @@ interface RenderAppResult {
|
|
|
241
246
|
head?: DocumentHead;
|
|
242
247
|
/** Вклад в `<head>` готовой разметкой — стили, собранные во время рендера. */
|
|
243
248
|
headHtml?: string;
|
|
249
|
+
/** Данные документа, состав которых знает шаблон хоста. */
|
|
250
|
+
data?: Record<string, unknown>;
|
|
244
251
|
/** Адрес для 3xx. */
|
|
245
252
|
redirect?: string;
|
|
246
253
|
/**
|
package/island/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@foxford/den",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.2",
|
|
4
4
|
"description": "Den — декларативный метафреймворк Foxford (core runtime)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"foxford",
|
|
@@ -83,6 +83,7 @@
|
|
|
83
83
|
"bin",
|
|
84
84
|
"builder",
|
|
85
85
|
"chunk-3RX2OSUL.js",
|
|
86
|
+
"chunk-3X4WVHUU.cjs",
|
|
86
87
|
"chunk-6FNC3XMI.js",
|
|
87
88
|
"chunk-6QV4L6R2.cjs",
|
|
88
89
|
"chunk-A6ZPAM6Z.cjs",
|
|
@@ -91,15 +92,14 @@
|
|
|
91
92
|
"chunk-KQAB6C6Q.cjs",
|
|
92
93
|
"chunk-MCN4GFEQ.js",
|
|
93
94
|
"chunk-RG7ZV5BD.js",
|
|
95
|
+
"chunk-SOH2TL2N.js",
|
|
94
96
|
"chunk-T5QVCXVB.cjs",
|
|
95
97
|
"chunk-TPBI6TOU.js",
|
|
96
|
-
"chunk-TPHJUDHG.js",
|
|
97
|
-
"chunk-UB3GCX73.cjs",
|
|
98
|
-
"chunk-URSWYSZF.js",
|
|
99
98
|
"chunk-WBHHHICS.js",
|
|
99
|
+
"chunk-XDM6J4LJ.cjs",
|
|
100
100
|
"chunk-XOJ2VWX4.cjs",
|
|
101
|
+
"chunk-XU5HUIPK.js",
|
|
101
102
|
"chunk-Z5BL4DJA.cjs",
|
|
102
|
-
"chunk-ZOU6W6ZQ.cjs",
|
|
103
103
|
"define-repository-CwAXed2X.d.cts",
|
|
104
104
|
"define-repository-q_T4hqeP.d.ts",
|
|
105
105
|
"define-slot-Cngzae6i.d.ts",
|
|
@@ -109,8 +109,8 @@
|
|
|
109
109
|
"define.d.ts",
|
|
110
110
|
"define.js",
|
|
111
111
|
"den.js",
|
|
112
|
-
"descriptor-
|
|
113
|
-
"descriptor-
|
|
112
|
+
"descriptor-BfsBDME1.d.cts",
|
|
113
|
+
"descriptor-D8ocBnTb.d.ts",
|
|
114
114
|
"index.cjs",
|
|
115
115
|
"index.d.cts",
|
|
116
116
|
"index.d.ts",
|
|
@@ -124,9 +124,9 @@
|
|
|
124
124
|
"server-render-CocWXQKC.d.ts",
|
|
125
125
|
"types-Dx5qGiwk.d.cts",
|
|
126
126
|
"types-Dx5qGiwk.d.ts",
|
|
127
|
-
"view-adapter-
|
|
128
|
-
"view-adapter-
|
|
127
|
+
"view-adapter-Bzcjotsn.d.ts",
|
|
128
|
+
"view-adapter-Cia9blgH.d.cts"
|
|
129
129
|
],
|
|
130
|
-
"sha": "
|
|
130
|
+
"sha": "7fa6f3e",
|
|
131
131
|
"scripts": {}
|
|
132
132
|
}
|
package/serve/index.cjs
CHANGED
|
@@ -5,7 +5,7 @@ var _chunkKQAB6C6Qcjs = require('../chunk-KQAB6C6Q.cjs');
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
var
|
|
8
|
+
var _chunkXDM6J4LJcjs = require('../chunk-XDM6J4LJ.cjs');
|
|
9
9
|
require('../chunk-XOJ2VWX4.cjs');
|
|
10
10
|
require('../chunk-6QV4L6R2.cjs');
|
|
11
11
|
|
|
@@ -69,14 +69,14 @@ function registerAssets(instance, source) {
|
|
|
69
69
|
|
|
70
70
|
var DEFAULT_SLOW_RENDER_MS = 1e3;
|
|
71
71
|
function claim(app) {
|
|
72
|
-
return
|
|
72
|
+
return _chunkXDM6J4LJcjs.normalizeRoutes.call(void 0, app.routes).map((route) => route.source);
|
|
73
73
|
}
|
|
74
74
|
function matchClaim(app, pathname) {
|
|
75
75
|
var _a, _b;
|
|
76
76
|
if (claim(app).length === 0) {
|
|
77
77
|
return {};
|
|
78
78
|
}
|
|
79
|
-
return (_b = (_a =
|
|
79
|
+
return (_b = (_a = _chunkXDM6J4LJcjs.matchRoute.call(void 0, app.routes, pathname)) == null ? void 0 : _a.params) != null ? _b : null;
|
|
80
80
|
}
|
|
81
81
|
function parseCookies(header) {
|
|
82
82
|
const cookies = {};
|
|
@@ -132,7 +132,7 @@ var appPlugin = (instance, options) => {
|
|
|
132
132
|
}
|
|
133
133
|
const startedAt = Date.now();
|
|
134
134
|
try {
|
|
135
|
-
const result = yield
|
|
135
|
+
const result = yield _chunkXDM6J4LJcjs.renderApp.call(void 0, app, { context: browserContext(req), params, pathname, search });
|
|
136
136
|
const elapsed = Date.now() - startedAt;
|
|
137
137
|
if (elapsed >= slowRenderMs) {
|
|
138
138
|
serveLog.warn(`\u043C\u0435\u0434\u043B\u0435\u043D\u043D\u044B\u0439 \u0440\u0435\u043D\u0434\u0435\u0440 \xAB${pathname}\xBB: ${String(elapsed)}\u043C\u0441`);
|
package/serve/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FastifyInstance, FastifyPluginAsync } from 'fastify';
|
|
2
|
-
import { I as IslandDescriptor } from '../descriptor-
|
|
2
|
+
import { I as IslandDescriptor } from '../descriptor-BfsBDME1.cjs';
|
|
3
3
|
import { A as AppRoute } from '../routes-B0hDrkiF.cjs';
|
|
4
4
|
import '../define-slot-DYNCLDJY.cjs';
|
|
5
5
|
import '../types-Dx5qGiwk.cjs';
|
package/serve/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FastifyInstance, FastifyPluginAsync } from 'fastify';
|
|
2
|
-
import { I as IslandDescriptor } from '../descriptor-
|
|
2
|
+
import { I as IslandDescriptor } from '../descriptor-D8ocBnTb.js';
|
|
3
3
|
import { A as AppRoute } from '../routes-0uXJ0fux.js';
|
|
4
4
|
import '../define-slot-Cngzae6i.js';
|
|
5
5
|
import '../types-Dx5qGiwk.js';
|
package/serve/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { I as IslandDescriptor } from './descriptor-
|
|
1
|
+
import { I as IslandDescriptor } from './descriptor-D8ocBnTb.js';
|
|
2
2
|
import { S as ServerRenderResult } from './server-render-CocWXQKC.js';
|
|
3
3
|
import { L as LayerDefinition, h as LayerConfig } from './types-Dx5qGiwk.js';
|
|
4
4
|
import { Container, Token } from '@foxford/ioc';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { I as IslandDescriptor } from './descriptor-
|
|
1
|
+
import { I as IslandDescriptor } from './descriptor-BfsBDME1.cjs';
|
|
2
2
|
import { S as ServerRenderResult } from './server-render-CocWXQKC.cjs';
|
|
3
3
|
import { L as LayerDefinition, h as LayerConfig } from './types-Dx5qGiwk.cjs';
|
|
4
4
|
import { Container, Token } from '@foxford/ioc';
|